问题
在Android 7的机器上下载ktcp应用后,即使把ktcp的receiver组件全部disable掉,重启开机还是会启动ktcp
根据日志和dumpsys package com.ktcp.video发现CHRestoreBroadcastReceiver已经disable了,但是还是因为接收开机广播被拉起来
logcat日志 ActivityManager: Start proc 4216:com.ktcp.video/u0a59 for broadcast com.ktcp.video/.receiver.CHRestoreBroadcastReceiver dumpsys信息 disabledComponents: …… com.ktcp.video.receiver.CHRestoreBroadcastReceiver
分析
思路1:完整了解Android是如何通过disable component禁止应用启动的
接收开机广播启动进程的日志如下,在processNextBroadcast()通过startProcessLocked()启动的
BroadcastQueue: Need to start app [background] ****** for broadcast BroadcastRecord{82a3f50 u0 android.intent.action.BOOT_COMPLETED}
ActivityManager: startProcess: name=****** app=null knownToBeDead=true thread=null pid=-1
ActivityManager: startProcessLocked
ActivityManager: java.lang.Exception
ActivityManager: at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:3691)
ActivityManager: at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:3673)
ActivityManager: at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:3554)
ActivityManager: at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:1270)
ActivityManager: at com.android.server.am.ActivityManagerService.finishReceiver(ActivityManagerService.java:18784)
ActivityManager: at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:528)
ActivityManager: at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2813)
ActivityManager: at android.os.Binder.execTransact(Binder.java:565)
在这个地方将所有BOOT_COMPLETED的接收者打印出来发现receivers中有CHRestoreBroadcastReceiver
这个地方由于广播接收者太多一共64个,直接打印的话日志打不全,需要循环打印
1375 2411 V BroadcastQueue: recIdx=62, receivers.size()=64 1375 1799 V BroadcastQueue: recIdx=63, receivers.size()=64
那Android时怎么把disableComponet的receiver添加到receivers中的呢?
这里就涉及到Intent、IntentFilter、IntentResolve相关的逻辑,找深入理解Android卷II看看整体逻辑,在加日志分析
发现是在开机阶段PackageManager扫描apk包时直接添加上了,这样整个流程就搞明白了
CHRestoreBroadcastReceiver明明状态时COMPONET_ENABLED_STATE_DISABLED,但是还是通过addFilter加到接收者队列中了
W PackageManager: ==> For Activity com.ktcp.video.receiver.CHRestoreBroadcastReceiver
W PackageManager: intent= ActivityIntentInfo{bc38401 com.ktcp.video/.receiver.CHRestoreBroadcastReceiver}
V PackageManager: type=receiver, a.getComponentName()=ComponentInfo{com.ktcp.video/com.ktcp.video.receiver.CHRestoreBroadcastReceiver}, 2
V IntentResolver: Adding filter: ActivityIntentInfo{bc38401 com.ktcp.video/.receiver.CHRestoreBroadcastReceiver}
V IntentResolver: java.lang.Exception
V IntentResolver: at com.android.server.IntentResolver.addFilter(IntentResolver.java:54)
V IntentResolver: at com.android.server.pm.PackageManagerService$ActivityIntentResolver.addActivity(PackageManagerService.java:11078)
V IntentResolver: at com.android.server.pm.PackageManagerService.scanPackageDirtyLI(PackageManagerService.java:8993)
V IntentResolver: at com.android.server.pm.PackageManagerService.scanPackageLI(PackageManagerService.java:8186)
V IntentResolver: at com.android.server.pm.PackageManagerService.scanPackageInternalLI(PackageManagerService.java:7338)
V IntentResolver: at com.android.server.pm.PackageManagerService.scanPackageLI(PackageManagerService.java:7048)
V IntentResolver: at com.android.server.pm.PackageManagerService.scanPackageLI(PackageManagerService.java:7024)
V IntentResolver: at com.android.server.pm.PackageManagerService.scanPackageTracedLI(PackageManagerService.java:6992)
V IntentResolver: at com.android.server.pm.PackageManagerService.-wrap1(PackageManagerService.java)
V IntentResolver: at com.android.server.pm.PackageManagerService$8.run(PackageManagerService.java:6891)
V IntentResolver: at com.android.server.pm.PackageManagerService.scanDirLI(PackageManagerService.java:6909)
V IntentResolver: at com.android.server.pm.PackageManagerService.scanDirTracedLI(PackageManagerService.java:6836)
V IntentResolver: at com.android.server.pm.PackageManagerService.<init>(PackageManagerService.java:2615)
V IntentResolver: at com.android.server.pm.PackageManagerService.main(PackageManagerService.java:2209)
V IntentResolver: at com.android.server.SystemServer.startBootstrapServices(SystemServer.java:456)
V IntentResolver: at com.android.server.SystemServer.run(SystemServer.java:330)
V IntentResolver: at com.android.server.SystemServer.main(SystemServer.java:217)
V IntentResolver: at java.lang.reflect.Method.invoke(Native Method)
V IntentResolver: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:925)
V IntentResolver: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:813)
V IntentResolver: Action: "android.intent.action.BOOT_COMPLETED"
V IntentResolver: Category: "android.intent.category.Default"
V IntentResolver: AutoVerify=false
V IntentResolver: Building Lookup Maps:
V IntentResolver: Action: android.intent.action.BOOT_COMPLETED
整个流程明白后,就可以有相应的解决方案了
注意事项:
(1)日志过长,logcat打不全
(2)试解决方法时,先加日志,日志符合预期后在真正添加,不然加的不对,系统经常挂掉