APP国密改造已进入尾声,最近一次是埋点库里埋点数据的加解密,需改造成国密。

业务代码合入主工程代码时,运行APP挂掉了。

提示如下错误信息:


2022-08-01 09:50:01.738 15234-15234/com.maomao.test.activity E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.maomao.test.activity:push, PID: 15234
    java.lang.RuntimeException: Unable to create application com.maomao.test.activity.tool.MyApp: com.tencent.tinker.loader.TinkerRuntimeException: Tinker Exception:No System TLS
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7409)
        at android.app.ActivityThread.access$2400(ActivityThread.java:251)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2284)
        at android.os.Handler.dispatchMessage(Handler.java:110)
        at android.os.Looper.loop(Looper.java:219)
        at android.app.ActivityThread.main(ActivityThread.java:8393)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)
     Caused by: com.tencent.tinker.loader.TinkerRuntimeException: Tinker Exception:No System TLS
        at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreateImpl_$noinline$(TinkerApplicationInlineFence.java:104)
        at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreate(TinkerApplicationInlineFence.java:110)
        at com.tencent.tinker.loader.app.TinkerApplication.onCreate(TinkerApplication.java:153)
        at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1202)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7393)
        at android.app.ActivityThread.access$2400(ActivityThread.java:251) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2284) 
        at android.os.Handler.dispatchMessage(Handler.java:110) 
        at android.os.Looper.loop(Looper.java:219) 
        at android.app.ActivityThread.main(ActivityThread.java:8393) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055) 
     Caused by: java.lang.AssertionError: No System TLS
        at okhttp3.internal.Util.assertionError(Util.java:504)
        at okhttp3.OkHttpClient.newSslSocketFactory(OkHttpClient.java:296)
        at okhttp3.OkHttpClient.<init>(OkHttpClient.java:258)
        at okhttp3.OkHttpClient$Builder.build(OkHttpClient.java:1040)
        at com.maomao.test.activity.net.okhttp.OkHttpFactory.initMTPClient(OkHttpFactory.java:507)
        at com.maomao.test.activity.net.okhttp.OkHttpFactory.initClient(OkHttpFactory.java:144)
        at com.maomao.test.activity.net.okhttp.OkHttpFactory.<init>(OkHttpFactory.java:123)
        at com.maomao.test.activity.net.okhttp.OkHttpFactory.getInstance(OkHttpFactory.java:468)
        at com.maomao.test.activity.globaldata.GlobalAppContainer.getBaseOKHttpFactory(GlobalAppContainer.java:138)
        at com.maomao.test.activity.net.NetUtilsImpl.getAsync(NetUtilsImpl.java:33)
        at com.maomao.test.activity.net.NetUtils.getCms(NetUtils.java:165)
        at com.maomao.test.activity.net.pb.ProtoBufUtil.queryProtobufList(ProtoBufUtil.java:23)
        at com.maomao.test.activity.globaldata.InterfaceImp.queryProtobufList(InterfaceImp.java:144)
        at com.maomao.test.activity.myapp.MyAppLike.onCreate(MyAppLike.java:216)
        at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreateImpl_$noinline$(TinkerApplicationInlineFence.java:99)
        at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreate(TinkerApplicationInlineFence.java:110) 
        at com.tencent.tinker.loader.app.TinkerApplication.onCreate(TinkerApplication.java:153) 
        at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1202) 
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7393) 
        at android.app.ActivityThread.access$2400(ActivityThread.java:251) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2284) 
        at android.os.Handler.dispatchMessage(Handler.java:110) 
        at android.os.Looper.loop(Looper.java:219) 
        at android.app.ActivityThread.main(ActivityThread.java:8393) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055) 
     Caused by: java.security.KeyManagementException: java.security.KeyStoreException: BKS not found
        at com.android.org.conscrypt.SSLParametersImpl.createDefaultX509KeyManager(SSLParametersImpl.java:539)
        at com.android.org.conscrypt.SSLParametersImpl.getDefaultX509KeyManager(SSLParametersImpl.java:520)
        at com.android.org.conscrypt.SSLParametersImpl.<init>(SSLParametersImpl.java:128)
        at com.android.org.conscrypt.OpenSSLContextImpl.engineInit(OpenSSLContextImpl.java:111)
        at javax.net.ssl.SSLContext.init(SSLContext.java:326)
        at okhttp3.OkHttpClient.newSslSocketFactory(OkHttpClient.java:293)
        at okhttp3.OkHttpClient.<init>(OkHttpClient.java:258) 
        at okhttp3.OkHttpClient$Builder.build(OkHttpClient.java:1040) 
        at com.maomao.test.activity.net.okhttp.OkHttpFactory.initMTPClient(OkHttpFactory.java:507) 
        at com.maomao.test.activity.net.okhttp.OkHttpFactory.initClient(OkHttpFactory.java:144) 
        at com.maomao.test.activity.net.okhttp.OkHttpFactory.<init>(OkHttpFactory.java:123) 
        at com.maomao.test.activity.net.okhttp.OkHttpFactory.getInstance(OkHttpFactory.java:468) 
        at com.maomao.test.activity.globaldata.GlobalAppContainer.getBaseOKHttpFactory(GlobalAppContainer.java:138) 
        at com.maomao.test.activity.net.NetUtilsImpl.getAsync(NetUtilsImpl.java:33) 
        at com.maomao.test.activity.net.NetUtils.getCms(NetUtils.java:165) 
        at com.maomao.test.activity.net.pb.ProtoBufUtil.queryProtobufList(ProtoBufUtil.java:23) 
        at com.maomao.test.activity.globaldata.InterfaceImp.queryProtobufList(InterfaceImp.java:144) 
        at com.maomao.test.activity.myapp.MyAppLike.onCreate(MyAppLike.java:216) 
        at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreateImpl_$noinline$(TinkerApplicationInlineFence.java:99) 
        at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreate(TinkerApplicationInlineFence.java:110) 
        at com.tencent.tinker.loader.app.TinkerApplication.onCreate(TinkerApplication.java:153) 
        at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1202) 
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7393) 
        at android.app.ActivityThread.access$2400(ActivityThread.java:251) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2284) 
        at android.os.Handler.dispatchMessage(Handler.java:110) 
        at android.os.Looper.loop(Looper.java:219) 
        at android.app.ActivityThread.main(ActivityThread.java:8393) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055) 
     Caused by: java.security.KeyStoreException: BKS not found
        at java.security.KeyStore.getInstance(KeyStore.java:890)
        at com.android.org.conscrypt.KeyManagerFactoryImpl.engineInit(KeyManagerFactoryImpl.java:63)
        at javax.net.ssl.KeyManagerFactory.init(KeyManagerFactory.java:272)
        at com.android.org.conscrypt.SSLParametersImpl.createDefaultX509KeyManager(SSLParametersImpl.java:528)
        at com.android.org.conscrypt.SSLParametersImpl.getDefaultX509KeyManager(SSLParametersImpl.java:520) 
        at com.android.org.conscrypt.SSLParametersImpl.<init>(SSLParametersImpl.java:128) 
        at com.android.org.conscrypt.OpenSSLContextImpl.engineInit(OpenSSLContextImpl.java:111) 
        at javax.net.ssl.SSLContext.init(SSLContext.java:326) 
        at okhttp3.OkHttpClient.newSslSocketFactory(OkHttpClient.java:293) 
        at okhttp3.OkHttpClient.<init>(OkHttpClient.java:258) 
        at okhttp3.OkHttpClient$Builder.build(OkHttpClient.java:1040) 
        at com.maomao.test.activity.net.okhttp.OkHttpFactory.initMTPClient(OkHttpFactory.java:507) 
        at com.maomao.test.activity.net.okhttp.OkHttpFactory.initClient(OkHttpFactory.java:144) 
        at com.maomao.test.activity.net.okhttp.OkHttpFactory.<init>(OkHttpFactory.java:123) 
        at com.maomao.test.activity.net.okhttp.OkHttpFactory.getInstance(OkHttpFactory.java:468) 
        at com.maomao.test.activity.globaldata.GlobalAppContainer.getBaseOKHttpFactory(GlobalAppContainer.java:138) 
        at com.maomao.test.activity.net.NetUtilsImpl.getAsync(NetUtilsImpl.java:33) 
        at com.maomao.test.activity.net.NetUtils.getCms(NetUtils.java:165) 
        at com.maomao.test.activity.net.pb.ProtoBufUtil.queryProtobufList(ProtoBufUtil.java:23) 
        at com.maomao.test.activity.globaldata.InterfaceImp.queryProtobufList(InterfaceImp.java:144) 
        at com.maomao.test.activity.myapp.MyAppLike.onCreate(MyAppLike.java:216) 
        at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreateImpl_$noinline$(TinkerApplicationInlineFence.java:99) 
        at com.tencent.tinker.entry.TinkerApplicationInlineFence.onCreate(TinkerApplicationInlineFence.java:110) 
        at com.tencent.tinker.loader.app.TinkerApplication.onCreate(TinkerApplication.java:153) 
        at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1202) 
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:7393) 
        at android.app.ActivityThread.access$2400(ActivityThread.java:251) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2284) 
        at android.os.Handler.dispatchMessage(Handler.java:110) 
        at android.os.Looper.loop(Looper.java:219) 
        at android.app.ActivityThread.main(ActivityThread.java:8393) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055) 
     Caused by: java.security.NoSuchAlgorithmException: BKS KeyStore not available
        at sun.security.jca.GetInstance.getInstance(GetInstance.java:159)
        at java.security.Security.getImpl(Security.java:628)
2022-08-01 09:50:01.738 15234-15234/com.maomao.test.activity E/AndroidRuntime:     at java.security.KeyStore.getInstance(KeyStore.java:887)

看到问题一脸懵,国密改造并没有改网络请求相关的代码。
而且本地数据库,密码加密都改造完上线了,最后埋点改造出了问题,不知从何查起;

此时我的畏难情绪达到顶点,发愁,无从下手。

经过几个日夜的情绪斗争,终于决定正视问题,解决它!

问题排查思路历程

(一)

首先“百度”了一下报错信息“java.lang.AssertionError: No System TLS”和“java.security.KeyStoreException: BKS not found”。

全网几乎没有答案,唯一一个匹配的问题,也是没有答案的。

最后在这几个博客文章中找到启发:

但是这些文章并没有解决我的问题。

(二)

然后我尝试打印出问题时的providerList里面有哪些内容。

发现我添加的代码没有生效。
添加provider代码如下:

    static {
        Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Log.i("sys", "运行环境没有BouncyCastleProvider");
            Security.addProvider(new BouncyCastleProvider());
        }
    }

我在方法触发之前和触发之后都分别打印了一下所有的provider:

Provider[] providers = Security.getProviders();
        for (Provider provider : providers) {
            Log.e("e", "getProviders before provider name:" + provider.getName() + ",version:" + provider.getVersion() + ",className:" + provider.getClass().getName());
        }

//此处调用static代码块

providers = Security.getProviders();
        for (Provider provider : providers) {
            Log.e("e", "getProviders after provider:" + provider.getName());
        }

打印的日志如下:


getProviders before provider name:AndroidNSSP,version:1.0,className:android.security.net.config.NetworkSecurityConfigProvider
getProviders before provider name:AndroidOpenSSL,version:1.0,className:com.android.org.conscrypt.OpenSSLProvider
getProviders before provider name:CertPathProvider,version:1.0,className:sun.security.provider.CertPathProvider
getProviders before provider name:AndroidKeyStoreBCWorkaround,version:1.0,className:android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
getProviders before provider name:BC,version:1.61,className:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
getProviders before provider name:HarmonyJSSE,version:1.0,className:com.android.org.conscrypt.JSSEProvider
getProviders before provider name:AndroidKeyStore,version:1.0,className:android.security.keystore.AndroidKeyStoreProvider
getProviders after provider:AndroidNSSP
getProviders after provider:AndroidOpenSSL
getProviders after provider:CertPathProvider
getProviders after provider:AndroidKeyStoreBCWorkaround
getProviders after provider:HarmonyJSSE
getProviders after provider:AndroidKeyStore

有两个发现。

  • 一个是android自带了BouncyCastleProvider,版本是1.61
  • 第二个是我执行的Security.addProvider(new BouncyCastleProvider());代码没有生效。

网上找到一篇关于setProvider不生效的帖子:
https://www.cnblogs.com/zhangyy3/p/13672261.html

于是我怀疑是我BC库的jar包没有签名导致给Java设置Security的值无法验证,导致插入失败

jar包文件签名步骤:Java/Android :Jar包签名

原本是想签名一下jar包再继续验证,但是签名路程坎坷,不方便拿到签名文件,所以这条路走不通。

然后又发现另一个疑点:我的BC库版本比Android自带的BC库版本低。
有可能是低版本无法覆盖高版本的BC库,导致插入失败。

解决版本问题需要把BC库源码下载下来,改一下BouncyCastleProvider.java的name,起一个不叫“BC”的名字。就不会与系统BC库冲突。
(这个方案是领导想出来的,他觉得非常有把握。我认为风险很高,手动编译源码,不知道会有多少坑等着我……)

这个方案或许能解决问题,但是如果Java在Security.addProvider时需要验证签名,改了也是白搭。

(三)

后面,转念一想:既然我可以改BouncyCastleProvider.java里的源码,为啥不自己自定义一个Provider,然后add进去试试呢?如果自定义的Provider能插入进去,说明Java在Security.addProvider时不验证签名,可以尝试改源码的方案。

于是我将BouncyCastleProvider.java源码拷贝了一份,将里面的

public static final String PROVIDER_NAME = "BC";

改成了

public static final String PROVIDER_NAME = "BCTEMP";

然后测试代码改成了

Provider[] providers = Security.getProviders();
        for (Provider provider : providers) {
            Log.e("e", "getProviders before provider name:" + provider.getName() + ",version:" + provider.getVersion() + ",className:" + provider.getClass().getName());
        }

Security.addProvider(new BouncyCastleProvider());

providers = Security.getProviders();
        for (Provider provider : providers) {
            Log.e("e", "getProviders after provider:" + provider.getName());
        }

打印日志如下:

getProviders before provider name:AndroidNSSP,version:1.0,className:android.security.net.config.NetworkSecurityConfigProvider
getProviders before provider name:AndroidOpenSSL,version:1.0,className:com.android.org.conscrypt.OpenSSLProvider
getProviders before provider name:CertPathProvider,version:1.0,className:sun.security.provider.CertPathProvider
getProviders before provider name:AndroidKeyStoreBCWorkaround,version:1.0,className:android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
getProviders before provider name:BC,version:1.61,className:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
getProviders before provider name:HarmonyJSSE,version:1.0,className:com.android.org.conscrypt.JSSEProvider
getProviders before provider name:AndroidKeyStore,version:1.0,className:android.security.keystore.AndroidKeyStoreProvider
getProviders after provider:AndroidNSSP
getProviders after provider:AndroidOpenSSL
getProviders after provider:CertPathProvider
getProviders after provider:AndroidKeyStoreBCWorkaround
getProviders after provider:HarmonyJSSE
getProviders after provider:AndroidKeyStore
getProviders after provider:BCTEMP

验证结果:名叫“BCTEMP”的provider添加成功了。

这个结果说明:

  1. Security.addProvider不校验签名,任何继承Provider的类都可以被添加进去;

这就更加无法解释为啥我之前的Security.addProvider没有添加成功了。

  • 第一个签名的疑问已经打消,因为自定义代码没有签名也能生效;
  • 第二个版本低的问题,因为我是先删除后添加,理论上不存在版本覆盖的问题。

(四)

于是我又多打印了一些日志。在下面这段代码

    static {
        Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Log.i("sys", "运行环境没有BouncyCastleProvider");
            Security.addProvider(new BouncyCastleProvider());
        }
    }

的前前后后也加了日志:

    static {
        Log.e("e", "static current Thread name:" + Thread.currentThread().getName() + ",Thread id:" + Thread.currentThread().getName());
        Provider[] providers = Security.getProviders();
        for (Provider provider : providers) {
            Log.e("e", "static getProviders before provider name:" + provider.getName() + ",version:" + provider.getVersion() + ",className:" + provider.getClass().getName());
        }
        Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
        Log.e("e", "static getProviders remove provider result:" + Security.getProvider(BouncyCastleProvider.PROVIDER_NAME));
        providers = Security.getProviders();
        for (Provider provider : providers) {
            Log.e("e", "static getProviders remove provider name:" + provider.getName() + ",version:" + provider.getVersion() + ",className:" + provider.getClass().getName());
        }
        int result = Security.addProvider(new BouncyCastleProvider());
        Log.e("e", "static getProviders add provider result:" + result);

        providers = Security.getProviders();
        for (Provider provider : providers) {
            Log.e("e", "static getProviders add provider name:" + provider.getName() + ",version:" + provider.getVersion() + ",className:" + provider.getClass().getName());
        }
    }

打印结果:



getProviders before provider name:AndroidNSSP,version:1.0,className:android.security.net.config.NetworkSecurityConfigProvider
getProviders before provider name:AndroidOpenSSL,version:1.0,className:com.android.org.conscrypt.OpenSSLProvider
getProviders before provider name:CertPathProvider,version:1.0,className:sun.security.provider.CertPathProvider
getProviders before provider name:AndroidKeyStoreBCWorkaround,version:1.0,className:android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
getProviders before provider name:BC,version:1.61,className:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
getProviders before provider name:HarmonyJSSE,version:1.0,className:com.android.org.conscrypt.JSSEProvider
getProviders before provider name:AndroidKeyStore,version:1.0,className:android.security.keystore.AndroidKeyStoreProvider



static getProviders before provider name:AndroidNSSP,version:1.0,className:android.security.net.config.NetworkSecurityConfigProvider
static getProviders before provider name:AndroidOpenSSL,version:1.0,className:com.android.org.conscrypt.OpenSSLProvider
static getProviders before provider name:CertPathProvider,version:1.0,className:sun.security.provider.CertPathProvider
static getProviders before provider name:AndroidKeyStoreBCWorkaround,version:1.0,className:android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
static getProviders before provider name:BC,version:1.61,className:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
static getProviders before provider name:HarmonyJSSE,version:1.0,className:com.android.org.conscrypt.JSSEProvider
static getProviders before provider name:AndroidKeyStore,version:1.0,className:android.security.keystore.AndroidKeyStoreProvider


getProviders after provider name:AndroidNSSP,version:1.0,className:android.security.net.config.NetworkSecurityConfigProvider
getProviders after provider name:AndroidOpenSSL,version:1.0,className:com.android.org.conscrypt.OpenSSLProvider
getProviders after provider name:CertPathProvider,version:1.0,className:sun.security.provider.CertPathProvider
getProviders after provider name:AndroidKeyStoreBCWorkaround,version:1.0,className:android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
getProviders after provider name:BC,version:1.61,className:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
getProviders after provider name:HarmonyJSSE,version:1.0,className:com.android.org.conscrypt.JSSEProvider
getProviders after provider name:AndroidKeyStore,version:1.0,className:android.security.keystore.AndroidKeyStoreProvider


static getProviders after provider name:AndroidOpenSSL,version:1.0,className:com.android.org.conscrypt.OpenSSLProvider
static getProviders after provider name:CertPathProvider,version:1.0,className:sun.security.provider.CertPathProvider
static getProviders after provider name:AndroidKeyStoreBCWorkaround,version:1.0,className:android.security.keystore.AndroidKeyStoreBCWorkaroundProvider
static getProviders after provider name:BC,version:1.61,className:com.android.org.bouncycastle.jce.provider.BouncyCastleProvider
static getProviders after provider name:HarmonyJSSE,version:1.0,className:com.android.org.conscrypt.JSSEProvider
static getProviders after provider name:AndroidKeyStore,version:1.0,className:android.security.keystore.AndroidKeyStoreProvider
static getProviders after provider name:BC,version:1.58,className:com.org.bouncycastle.jce.provider.BouncyCastleProvider

验证发现:

  1. provider name:BC,version:1.58已经被添加进去了。
  2. getProviders after provider的日志在static getProviders after provider之前打印。

这个结果说明:

  1. static{}代码块执行Security.addProvider,是在在调用者调用完static{}代码块代码之后。
  2. static{}代码块执行和调用者代码执行不在同一个线程导致了1的结果。

随后我添打印了一下各自当前线程,得到了证实,确实不在同一线程。

问题根本原因是:

static{}代码块是在子线程执行的(因为埋点调用国密加解密是在子线程执行),而调用方是主线程(埋点调用方和okhttp初始化同在主线程)。在执行Security.removeProvider之后,又进入了主线程中执行okhttp初始化。而okhttp初始化需要用到名叫“BC”的Provider,此时“BC”的Provider正好已经被删除了,新的Security.addProvider还没添加进来,导致okhttp初始化时报错:No System TLS / BKS not found

解决方案

找到问题原因就好办了。现在问题演变成了多线程同步问题,如何保证在okhttp初始化之前,“BC”Provider已经初始化好了。

所以最后解决方案是:把static{}代码块执行的时机,放在埋点库调用国密加解密、和okhttp初始化之前,并且在主线程执行。

这样,可以保证埋点库调用国密加解密开子线程之前,static{}代码块已经执行过了。利用线程之间数据共享和static{}代码块只会执行一次的原理,后面执行埋点库开子线程调用国密加解密时,static{}代码块已经执行过,且无需再执行static{}代码块就能进行后面的操作。

小结

这是一次超乎想象的难题,问题起因毫无头绪,排查非常困难,而且影响面极大,应用初始化的时候就crash了。

我有时候会逃避问题,见到这么棘手的问题,要是百度不能解决,我就很想放弃。但是这是个大问题,埋点库必须要上线,国密也必须要上线,APP坚决不能崩溃!

所以只能硬着头皮上了。

回过头来发现:在毫无头绪的时候,多打印日志观察现象,是一个好的解决思路。

逃避不能解决任何问题。最后还是要回到问题本身,正视问题,观察问题原因,不断怀疑提问,然后顺着自己的提问判断假设是否成立,总结出问题的真正原因所在。

这次的经验对我非常重要。我才发现“畏难心理”是一个非常不利于帮助解决问题的情绪。再大的问题,只要你慢慢跟他耗,总会有解决的一天,但是如果什么都不做,那就会毫无进展。

勇敢毛毛,不怕困难。

冲呀~