售后报一个问题,升级系统后,某彩票apk 打开后黑屏, 但是该apk再该平台升级以前是运行良好的.
查看log,发现 报以下问题:
5252 01-01 13:49:08.567 I/System.out(13643):
java.lang.NoSuchMethodError: org.jsoup.parser.Parser.xmlParser
5253 01-01 13:49:08.567 I/System.out(13643): at cn.pcai.echart.core.log.LogIniter.parseConf(LogIniter.java:45)
5254 01-01 13:49:08.567 I/System.out(13643): at cn.pcai.echart.core.log.LogIniter.doReset(LogIniter.java:120)
5255 01-01 13:49:08.567 I/System.out(13643): at cn.pcai.echart.core.log.LogIniter.reset(LogIniter.java:36)
5256 01-01 13:49:08.567 I/System.out(13643): at cn.pcai.echart.ext.service.WorkspaceServiceImpl.initApp(WorkspaceServiceImpl.java:39)
5257 01-01 13:49:08.567 I/System.out(13643): at cn.pcai.echart.ext.BeanFactoryIniter.init(BeanFactoryIniter.java:65)
5258 01-01 13:49:08.567 I/System.out(13643): at cn.pcai.echart.MyApplication.onCreate(MyApplication.java:56)
5259 01-01 13:49:08.567 I/System.out(13643): at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1007)
5260 01-01 13:49:08.567 I/System.out(13643): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4332)
5261 01-01 13:49:08.567 I/System.out(13643): at android.app.ActivityThread.access$1500(ActivityThread.java:135)
5262 01-01 13:49:08.567 I/System.out(13643): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
5263 01-01 13:49:08.567 I/System.out(13643): at android.os.Handler.dispatchMessage(Handler.java:102)
5264 01-01 13:49:08.567 I/System.out(13643): at android.os.Looper.loop(Looper.java:136)
5265 01-01 13:49:08.567 I/System.out(13643): at android.app.ActivityThread.main(ActivityThread.java:5012)
5266 01-01 13:49:08.567 I/System.out(13643): at java.lang.reflect.Method.invokeNative(Native Method)
5267 01-01 13:49:08.567 I/System.out(13643): at java.lang.reflect.Method.invoke(Method.java:515)
5268 01-01 13:49:08.567 I/System.out(13643): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:806)
5269 01-01 13:49:08.567 I/System.out(13643): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
5270 01-01 13:49:08.567 I/System.out(13643): at dalvik.system.NativeStart.main(Native Method)
5271 01-01 13:49:08.581 I/MTK_FPP ( 915): function start:fpp_gpio_configure,arg:gpio_index=16
5272 01-01 13:49:08.581 I/MTK_FPP ( 915): function end:fpp_gpio_configure,arg:rRet=0
从log看是找不到某个方法, 我们反编译了改apk, 却发现反编译后的代码里包含了 改方法.
这就有点奇怪,明明apk自身带改方法,为什么却报找不到改方法呢?
于是我们大胆推测, 我们在新的系统里的BOOTCLASSPATH里添加了某个jar包, 该jar包也有一个 org.jsoup.parser.Parser类, 但是没有xmlParse()方法.
于是我们再板子里搜索:
运行命令:
grep -r "jsoup" /
结果:
.........................................................
./data/dalvik-cache/system@framework@com.tcl.tclvoicecontrol.jar@classes.dex:Lorg/jsoup/nodes/Entities;
./data/dalvik-cache/system@framework@com.tcl.tclvoicecontrol.jar@classes.dex:'Lorg/jsoup/nodes/Node$OuterHtmlVisitor;
./data/dalvik-cache/system@framework@com.tcl.tclvoicecontrol.jar@classes.dex:Lorg/jsoup/nodes/Node;
./data/dalvik-cache/system@framework@com.tcl.tclvoicecontrol.jar@classes.dex:Lorg/jsoup/nodes/TextNode;
./data/dalvik-cache/system@framework@com.tcl.tclvoicecontrol.jar@classes.dex: Lorg/jsoup/nodes/XmlDeclaration;
./data/dalvik-cache/system@framework@com.tcl.tclvoicecontrol.jar@classes.dex:"Lorg/jsoup/parser/CharacterReader;
./data/dalvik-cache/system@framework@com.tcl.tclvoicecontrol.jar@classes.dex:Lorg/jsoup/parser/ParseError;
./data/dalvik-cache/system@framework@com.tcl.tclvoicecontrol.jar@classes.dex:Lorg/jsoup/parser/Parser;
./data/dalvik-cache/system@framework@com.tcl.tclvoicecontrol.jar@classes.dex:Lorg/jsoup/parser/Tag;
./data/dalvik-cache/system@framework@com.tcl.tclvoicecontrol.jar@classes.dex:Lorg/jsoup/parser/Token$1;
.....................................................
看到了么? 有一个叫com.tcl.tclvoicecontrol.jar 包里面有org.jsoup.parser.Parser类, 我们在看看BOOTCLASSPATH里是否有这个jar包.
运行: cat $BOOTCLASSPATH
结果:
/system/bin/sh: cat: /system/framework/core.jar:/system/framework/conscrypt.jar:/system/framework/okhttp.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/framework2.jar:/system/framework/telephony-common.jar:/system/framework/voip-common.jar:/system/framework/mms-common.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/system/framework/webviewchromium.jar:/system/framework/com.mediatek.util.jar:/system/framework/com.mediatek.tv.jar:/system/framework/com.mediatek.tv.custom.jar:/system/framework/com.mediatek.dm.jar:/system/framework/com.mediatek.common.capture.jar:/system/framework/com.mediatek.record.jar:/system/framework/com.mediatek.common.PhotoPlayer.jar:/system/framework/com.mediatek.common.powercontrol.jar:/system/framework/com.mediatek.wfdsink.jar:/system/framework/com.tcl.tvmanager.jar:/system/framework/android.tclwidget.jar:/system/framework/com.tcl.device.authentication.jar:/system/framework/com.tcl.deviceinfo.jar:/system/framework/com.tcl.devicemanager.jar:/system/framework/com.tcl.seeker.jar:/system/framework/com.tcl.os.storage.jar:/system/framework/com.tcl.os.system.jar:/system/framework/com.tcl.net.ethernet.jar:/system/framework/com.tcl.media.jar:/system/framework/com.tcl.screenrecorder.jar:/system/framework/com.tcl.adsystem.jar:/system/framework/com.tcl.net.pppoe.jar:/system/framework/com.tcl.tclvoicecontrol.jar
果然com.tcl.tclvociecontorl.jar再BOOTCLASSPATH里,
接着把com.tcl.tclvoicecontrol进行了反编译, 发现org.jsoup.parser.Parser类里果然没有xmlParse()方法, 这下原因终于确定了.
结论: 每当虚拟机启动的时候 ,就会预先加载BOOTCLASSPATH里的类, 如果BOOTCLASSPATH里的某些类和apk自身带的某些类报名一样, 那么会使用BOOTCLASSPATH里的类, 因为这些类是在虚拟机启动的时候加载的. 这就会造成一个很奇怪的现象, apk里自带某些类,却找不到该类的一些方法,因为bootclasspath里的同名的类没有该方法.