android 打包混淆,debug可以正常使用,混淆正式包就一点就崩
打包混淆,debug可以正常使用,混淆正式包就一点就崩 开始检查
前言
也正式打包过不少项目了,感觉这个地方并不会坑到自己,结果最近还是倒在了这个地方。。。打包完的项目一点就崩,令人费解。先来说说我遇到的问题,和解决过程吧,想直接知道答案的朋友直接滑到最下面即可。
问题
崩溃信息如下:
07-15 16:18:41.720 11600-11600/? E/AndroidRuntime: FATAL EXCEPTION: mainProcess: com.rdwl.siglight.public, PID: 11600java.lang.ExceptionInInitializerErrorat com.rdwl.siglight.app.IMService.<init>(IMService.java:4)at java.lang.Class.newInstance(Native Method)at android.app.ActivityThread.handleCreateService(ActivityThread.java:3003)at android.app.ActivityThread.access$1900(ActivityThread.java:180)at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1558)at android.os.Handler.dispatchMessage(Handler.java:111)at android.os.Looper.loop(Looper.java:207)at android.app.ActivityThread.main(ActivityThread.java:5710)at java.lang.reflect.Method.invoke(Native Method)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:900)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)Caused by: java.lang.NullPointerException: throw with null exceptionat com.loopj.android.http.AsyncHttpClient.getDefaultSchemeRegistry(AsyncHttpClient.java:6)at com.loopj.android.http.AsyncHttpClient.<init>(AsyncHttpClient.java:4)at com.loopj.android.http.AsyncHttpClient.<init>(AsyncHttpClient.java:1)at com.rd.rd_cloudlibrary.designManger.IMSocketManager.<init>(IMSocketManager.java:5)at com.rd.rd_cloudlibrary.designManger.IMSocketManager.<clinit>(IMSocketManager.java:1)at com.rdwl.siglight.app.IMService.<init>(IMService.java:4) at java.lang.Class.newInstance(Native Method) at android.app.ActivityThread.handleCreateService(ActivityThread.java:3003) at android.app.ActivityThread.access$1900(ActivityThread.java:180) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1558) at android.os.Handler.dispatchMessage(Handler.java:111) at android.os.Looper.loop(Looper.java:207) at android.app.ActivityThread.main(ActivityThread.java:5710) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:900) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
重要信息就是我的一个服务中调用的第三方类初始化失败,失败在这里:
com.loopj.android.http.AsyncHttpClient.getDefaultSchemeRegistry(AsyncHttpClient.java:6)
说这个工作对象为空指针了
开始检查
一般来说,遇到空指针第一步就是去看代码有没有问题加个判断就好了。现在问题是,这个初始化代码是第三方的aar包里的,无法修改。。。而且这个包在之前的项目一直有用,没有出现过这种问题。这下我就懵了。
先硬着头皮去看代码吧
能看到最后返回了 这么一个东西,而这个东西来自 org..http,啥也不管,先检查一下是否把这个加到混淆里面了
-dontwarn org.apache.**
-keep class org.apache.** { *; }
再来打包,运行
失败
还是一个鬼样
这时候发现了stry(.java:6)这个第6行代码好像不是我们正常的java代码,我猜是混淆后的地方
OK,那就分析打包文件
找到文件开始分析
找到对应的方法,右键能看到显示代码的选项
找到第六行,当然不用我们数出第六行,而是line 6
这时候就发现了一个问题,这里只使用了的init方法,也就是初始化,而没有使用.的方法,但是这个方法是java代码里面有的,这就奇了怪了。。。
打开混淆后的文件看
果然这个方法不见了,难道被打包的代码优化给压缩了?
那就不压缩试一下
需要把 = true改成 = false
激动,再来打包,运行
失败
看来没那么简单啊
再来
混淆规则里面也是有优化规则的,顺便修改一下
激动,再来打包,运行
失败
应该是路子走错了。。。突然意识到,跟压缩没有关系,因为如果使用到的话,那个方法是肯定不会压缩的。会不会是版本的问题?
<uses-sdkandroid:minSdkVersion="21"android:targetSdkVersion="26" />
迅速修改了版本号
激动,再来打包,运行
失败
编译就崩溃了
Manifest merger failed : uses-sdk:minSdkVersion 21 cannot be smaller than version 22 declared in library [iflyos-app-sdk.aar] /Users/yangdilong/.gradle/caches/transforms-2/files-2.1/3541378cbb10e114127343eaa786c61f/AndroidManifest.xml as the library might be using APIs not available in 21Suggestion: use a compatible library with a minSdk of at most 21,or increase this project's minSdk version to at least 22,or use tools:overrideLibrary="com.iflytek.home.sdk" to force usage (may lead to runtime failures)
嘿嘿,又一个第三方包有最低要求。。。
mmp
不管了,先排除这个版本问题,加个忽略
在里加
<uses-sdktools:overrideLibrary="com.iflytek.home.sdk" />
激动,再来打包,运行
失败
没有丝毫改变。。。难道我又走错路了?
想起还有一个build.,顺带也改了吧
将3.4.2改成3.2.0
再来打包,运行
!!!
成功了!
我的天。。。。还真是版本号问题。。。用 真的是单是版本更新都能有很多坑。无语凝噎,留下了没技术的泪水。。。
最后,感谢两篇文章
@QM_姚丹 ---- 错误use tools:=“com..” to force usage
@ ---- 代码混淆(包教包会)