也正式打包过不少项目了,感觉这个地方并不会坑到自己,结果最近还是倒在了这个地方。。。打包完的项目一点就崩,令人费解。先来说说我遇到的问题,和解决过程吧,想直接知道答案的朋友直接滑到最下面即可。
崩溃信息如下:
07-15 16:18:41.720 11600-11600/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.rdwl.siglight.public, PID: 11600
java.lang.ExceptionInInitializerError
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)
Caused by: java.lang.NullPointerException: throw with null exception
at 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包里的,无法修改。。。而且这个包在之前的项目一直有用,没有出现过这种问题。这下我就懵了。
先硬着头皮去看代码吧
能看到最后返回了 SchemeRegistry 这么一个东西,而这个东西来自 org.apache.http
,啥也不管,先检查一下是否把这个加到混淆里面了
-dontwarn org.apache.**
-keep class org.apache.** { *; }
还是一个鬼样
这时候发现了getDefaultSchemeRegistry(AsyncHttpClient.java:6)
这个第6行代码好像不是我们正常的java代码,我猜是混淆后的地方
OK,那就分析打包文件
找到文件开始分析
找到对应的方法,右键能看到显示代码的选项
找到第六行,当然不用我们数出第六行,而是line 6
这时候就发现了一个问题,这里只使用了SchemeRegistry
的init
方法,也就是初始化,而没有使用schemeRegistry.register
的方法,但是这个方法是java代码里面有的,这就奇了怪了。。。
打开混淆后的SchemeRegistry文件看
果然这个方法不见了,难道被打包的代码优化给压缩了?
那就不压缩试一下
需要把zipAlignEnabled = true
改成zipAlignEnabled = false
激动,再来打包,运行
emmmmm
看来没那么简单啊
再来
混淆规则里面也是有优化规则的,顺便修改一下
激动,再来打包,运行
emmmmm
应该是路子走错了。。。突然意识到,跟压缩没有关系,因为如果使用到的话,那个方法是肯定不会压缩的。会不会是版本的问题?
<uses-sdk
android:minSdkVersion="21"
android:targetSdkVersion="26" />
迅速修改了版本号
激动,再来打包,运行
emmmmm
编译就崩溃了
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 21
Suggestion: 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
不管了,先排除这个版本问题,加个忽略
在AndroidManifest
里加
<uses-sdk
tools:overrideLibrary="com.iflytek.home.sdk" />
激动,再来打包,运行
emmmmm
没有丝毫改变。。。难道我又走错路了?
想起还有一个build.gradle,顺带也改了吧
将3.4.2
改成3.2.0
再来打包,运行
!!!
我的天。。。。还真是版本号问题。。。用Android studio真的是单是版本更新都能有很多坑。无语凝噎,留下了没技术的泪水。。。
最后,感谢两篇文章
@QM_姚丹 ---- 错误use tools:overrideLibrary=“com.myworkframe.activity” to force usage
@csdn_mm ---- Android Studio 代码混淆(包教包会)