签名异常导致自动化apk无法启动


遇到的问题做个记录~

问题背景:生产原因需要切换代码分支,由原分支CTV_Baseline_6681_MP2切换到CTV_Baseline_6681_MP3,而两个分支的进版tag不一样;Apk是从同事手中拿到的,通过预装在system分区下的方式进行客制化。

问题描述:将客制化修改内容手动移植到MP3分支,编译升级软件后发现在factory_mode下自动化apk无法自启动。

分析过程:

遇到问题之后,通过Uart连接主板,在su权限下执行logcat命令(此命令不做过滤,会输出所有的信息内容)获取软件输出日志;其中发现一句

1 10-29 11:07:54.297  3061  3257 W ActivityManager: Unable to start service Intent { act=com.tpv.newfactorytest.FactoryTestService pkg=com.tpv.newfactorytest } U=0: not found

显示FactoryTestService这个服务没有找到,猜测可能是apk没有预装或者是FactoryTestService这个服务没有注册;

先查看了apk的预装情况,在system分区中有TPVFactest_0810.apkdata分区下有com.tpv.newfactorytest包名目录;然后拿到了apk的源码,该服务有在AndroidManifest.xml文件中注册

 1 <service
 2 
 3             android:name="com.tpv.newfactorytest.FactoryTestService"
 4 
 5             android:enabled="true"
 6 
 7             android:exported="true" >
 8 
 9             <intent-filter>
10 
11                 <action android:name="com.tpv.newfactorytest.FactoryTestService" />
12 
13             intent-filter>
14 
15 service>

尝试手动通过命令am startservice -n com.tpv.newfactorytest/.FactoryTestService启动服务,结果仍然无效。

接着重新查看logcat发现com.tpv.newfactorytest(pid=4812)被杀掉了;

1 10-29 11:08:00.986  3057  3600 I ActivityManager: Process com.tpv.newfactorytest (pid 4812) has died: fore SVC
2 
3 10-29 11:08:00.988  3057  3600 W ActivityManager: Scheduling restart of crashed service com.tpv.newfactorytest/.FactoryTestService in 7536ms
4 
5 10-29 11:08:00.998  3057  3109 W ActivityManager: setHasOverlayUi called on unknown pid: 4812
6 
7 10-29 11:08:01.032  3057  3102 W libprocessgroup: kill(-4812, 9) failed: No such process
8 
9 10-29 11:08:01.032  3057  3102 I libprocessgroup: Successfully killed process cgroup uid 1000 pid 4812 in 46ms

使用过滤功能把该进程的信息过滤出来,捕捉到关键信息点

1 10-29 11:07:57.920  4812  4812 E         : can not found class define:com/mediatek/twoworlds/tv/model/MtkTvAudioInfoBase
2 
3 10-29 11:07:57.921  4812  4812 F .newfactorytes: thread.cc:2148] No pending exception expected: java.lang.ClassNotFoundException: Didn't find class "com.mediatek.twoworlds.tv.model.MtkTvAudioInfoBase" on path: DexPathList[[zip file "/system/framework/org.apache.http.legacy.boot.jar", zip file "/system/app/TPVFactest_0810/TPVFactest_0810.apk"],nativeLibraryDirectories=[/system/app/TPVFactest_0810/lib/arm, /system/app/TPVFactest_0810/TPVFactest_0810.apk!/lib/armeabi, /system/lib, /system/product/lib, /system/lib, /system/product/lib]]

发现应用在库文件中找不到com.mediatek.twoworlds.tv.model.MtkTvAudioInfoBase这个类而抛出了java.lang.ClassNotFoundException异常。

 1 at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:134)
 2 
 3    at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:379)
 4 
 5    at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312)
 6 
 7    at java.lang.String java.lang.Runtime.nativeLoad(java.lang.String, java.lang.ClassLoader) (Runtime.java:-2)
 8 
 9    at void java.lang.Runtime.loadLibrary0(java.lang.ClassLoader, java.lang.String) (Runtime.java:1014)
10 
11    at void java.lang.System.loadLibrary(java.lang.String) (System.java:1669)
12 
13    at void com.mediatek.twoworlds.tv.TVNative.() (TVNative.java:77)
14 
15    at int com.mediatek.twoworlds.tv.TVNative.getMinMaxConfigValue_native(int, java.lang.String) (TVNative.java:-2)
16 
17    at int com.mediatek.twoworlds.tv.TVNativeWrapper.getMinMaxConfigValue_native(int, java.lang.String) (TVNativeWrapper.java:523)
18 
19    at int com.mediatek.twoworlds.tv.MtkTvConfigBase.getMinMaxConfigValue(int, java.lang.String) (MtkTvConfigBase.java:231)
20 
21    at int com.mediatek.twoworlds.tv.MtkTvConfigBase.getMinMaxConfigValue(java.lang.String) (MtkTvConfigBase.java:196)
22 
23    at void com.mediatek.twoworlds.factory.MtkTvFApiDisplayBase.() (MtkTvFApiDisplayBase.java:328)
24 
25    at void com.mediatek.twoworlds.factory.MtkTvFApiDisplay.() (MtkTvFApiDisplay.java:19)
26 
27    at com.mediatek.twoworlds.factory.MtkTvFApiDisplay com.mediatek.twoworlds.factory.MtkTvFApiDisplay.getInstance() (MtkTvFApiDisplay.java:26)
28 
29    at void com.tpv.newfactorytest.manager.PictureManager.(android.content.Context) (PictureManager.java:44)
30 
31    at com.tpv.newfactorytest.manager.PictureManager com.tpv.newfactorytest.manager.PictureManager.getInstance(android.content.Context) (PictureManager.java:87)
32 
33    at void com.tpv.newfactorytest.manager.CommandExecutor.init() (CommandExecutor.java:189)
34 
35    at void com.tpv.newfactorytest.manager.CommandExecutor.(android.content.Context) (CommandExecutor.java:170)
36 
37    at void com.tpv.newfactorytest.FactoryTestService.initial() (FactoryTestService.java:135)
38 
39    at void com.tpv.newfactorytest.FactoryTestService.onCreate() (FactoryTestService.java:61)
40 
41    at void android.app.ActivityThread.handleCreateService(android.app.ActivityThread$CreateServiceData) (ActivityThread.java:3532)
42 
43    at void android.app.ActivityThread.access$1300(android.app.ActivityThread, android.app.ActivityThread$CreateServiceData) (ActivityThread.java:199)
44 
45    at void android.app.ActivityThread$H.handleMessage(android.os.Message) (ActivityThread.java:1666)
46 
47    at void android.os.Handler.dispatchMessage(android.os.Message) (Handler.java:106)
48 
49    at void android.os.Looper.loop() (Looper.java:193)
50 
51    at void android.app.ActivityThread.main(java.lang.String[]) (ActivityThread.java:6669)
52 
53    at java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[]) (Method.java:-2)
54 
55    at void com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run() (RuntimeInit.java:493)
56 
57    at void com.android.internal.os.ZygoteInit.main(java.lang.String[]) (ZygoteInit.java:866)

通过反查代码MtkTvAudioInfoBase类在TvNative.java中有调用,但是调用路径都正常;到这里路被堵死了。

通过请教同事才知道,MTK平台两份代码进版tag不一样,签名有差异,会导致底层so库文件路径有差异;

最后重新使用MP3分支进行签名替换之后可以正常运行。