Android persistent属性研究

 

前段时间在研究telephony时,一直没有在framework下发现对telephony的初始化(PhoneFactory.java中的makeDefaultPhones函数)的调用。结果全局搜索之后发现在application PhoneApp(packages/apps/Phone)中调用了。但是application PhoneApp既没有被Broadcast唤醒,也没有被其他service调用,那么是Android是通过什么方式来启动PhoneApp,所以就发现了属性android:persistent。

AndroidManifest.xml定义中,application有这么一个属性android:persistent,根据字面意思来理解就是说该应用是可持久的,也即是常驻的应用。其实就是这么个理解,被android:persistent修饰的应用会在系统启动之后被AM启动。

AM首先去PM(PackageManagerService)中去查找设置了Android:persistent的应用

  1. public void systemReady(final Runnable goingCallback) {    
  2.             if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {    
  3.                 try {    
  4.                     List apps = AppGlobals.getPackageManager().    
  5.                         getPersistentApplications(STOCK_PM_FLAGS);    
  6.                     if (apps != null) {    
  7.                         int N = apps.size();    
  8.                         int i;    
  9.                         for (i=0; i<N; i++) {    
  10.                             ApplicationInfo info    
  11.                                 = (ApplicationInfo)apps.get(i);    
  12.                             if (info != null &&    
  13.                                     !info.packageName.equals("Android")) {    
  14.                                 addAppLocked(info);    
  15.                             }    
  16.                         }    
  17.                     }    
  18.                 } catch (RemoteException ex) {    
  19.                     // pm is in same process, this will never happen.     
  20.                 }    
  21.             }       
  22. }    

假如该被Android:persistent修饰的应用此时并未运行的话,那么AM将调用startProcessLocked启动该app,关于startProcessLocked不再描述,另外一篇文章《How to start a new process for Android?》中做了详细的介绍。

app的启动过程就是启动app所在的package对应的进程。

  1. final ProcessRecord addAppLocked(ApplicationInfo info) {    
  2.         ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);    
  3.         if (app == null) {    
  4.             app = newProcessRecordLocked(null, info, null);    
  5.             mProcessNames.put(info.processName, info.uid, app);    
  6.             updateLruProcessLocked(app, truetrue);    
  7.         }    
  8.         if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))    
  9.                 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {    
  10.             app.persistent = true;    
  11.             app.maxAdj = CORE_SERVER_ADJ;    
  12.         }    
  13.         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {    
  14.             mPersistentStartingProcesses.add(app);    
  15.             startProcessLocked(app, "added application", app.processName);    
  16.         }    
  17.         return app;    
  18.     }    



面介绍app所在的package对应的进程启动完成之后,app是如何被create的。

从文章《How to start a new process for Android?》中可知,zygote在创建新的进程均会启动它的mainThread android.app.ActivityThread,因此我们从ActivityThread的main函数中接着分析app的create过程。

在main中有下面这个操作

thread.attach(false);  

在attach过程中,ActivityThread会将对应的application attach到AM中去,交与AM去管理。这里需要注意一个变量

final ApplicationThread mAppThread = new ApplicationThread();  

mAppThread是一个ApplicationThread对象,mAppThread可以看作是当前进程主线程的核心,它负责处理本进程与其他进程(主要是AM)之间的通信,同时通过attachApplication将mAppThread的代理Binder传递给AM。

  1. private final void attach(boolean system) {    
  2.         sThreadLocal.set(this);    
  3.         mSystemThread = system;    
  4.         if (!system) {    
  5.             ViewRoot.addFirstDrawHandler(new Runnable() {    
  6.                 public void run() {    
  7.                     ensureJitEnabled();    
  8.                 }    
  9.             });    
  10.             Android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");    
  11.             RuntimeInit.setApplicationObject(mAppThread.asBinder());    
  12.             IActivityManager mgr = ActivityManagerNative.getDefault();    
  13.             try {    
  14.                 mgr.attachApplication(mAppThread);    
  15.             } catch (RemoteException ex) {    
  16.             }    
  17.         }    
  18.     }    

上面的attach代码中,我们顺着IPC调用AM的attachApplication过程再往下看。

在该过程中,AM调用到了IPC通信调用mAppThread的bindApplication;

  1. private final boolean attachApplicationLocked(IApplicationThread thread,    
  2.             int pid) {    
  3.         
  4.             thread.bindApplication(processName, app.instrumentationInfo != null    
  5.                     ? app.instrumentationInfo : app.info, providers,    
  6.                     app.instrumentationClass, app.instrumentationProfileFile,    
  7.                     app.instrumentationArguments, app.instrumentationWatcher, testMode,     
  8.                     isRestrictedBackupMode || !normalMode,    
  9.                     mConfiguration, getCommonServicesLocked());    
  10.             updateLruProcessLocked(app, falsetrue);    
  11.             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();    
  12. }    

mAppThread的bindApplication再通过消息机制向ActivityThread自身维护的handler发送BIND_APPLICATION消息。下面看看ActivityThread自身维护的handler对消息BIND_APPLICATION的处理,最终会调用到handleBindApplication函数

你会发现在handleBindApplication函数中有这么一句

mInstrumentation.callApplicationOnCreate(app);

我们最终在绕了好大一圈之后,调用了app的onCreate函数来启动这个application。


<think>好的,我需要回答用户如何通过ADB禁用Android系统中的Persistent属性。首先,我需要理解Persistent属性的作用。根据引用[3],Persistent属性会让应用在系统启动时自动启动并保持运行,通常用于系统核心应用。用户想要禁用这个属性,可能需要修改应用的AndroidManifest.xml文件,但直接通过ADB命令可能不太容易。 接下来,我需要查阅相关的ADB命令。引用[2]中提到了adb shell pm和adb shell am等工具,但没直接提到如何修改应用属性。可能的思路是覆盖资源或修改系统设置。引用[1]中的adb shell cmd overlay lookup可能用于查找资源,但不确定是否适用。引用[4]提到在Android12 MTK平台禁用ADB需要修改AdbService.java,这可能不相关,但说明系统属性可能需要修改底层代码或使用设备管理员权限。 另外,用户可能需要root权限才能修改系统应用的属性。如果没有root,可能需要使用adb shell命令临时停止应用,如adb shell am force-stop包名,但这只是临时措施。如果需要持久禁用,可能需要通过禁用应用组件,例如使用adb shell pm disable-user包名/组件名,但不确定是否对Persistent属性有效。 可能还需要检查应用是否在系统分区,如果是,可能需要重新挂载系统分区为可写,但这需要root。综上所述,正确的方法可能包括使用adb shell pm set-component-enabled来禁用组件,或者通过覆盖资源的方式修改属性,但具体步骤需要验证。 最后,确保回答结构清晰,分步骤说明可能的解决方法,并提醒用户需要root权限以及相关风险。</think>要通过ADB禁用Android系统的Persistent属性,需通过以下步骤操作: 1. **定位应用包名** 使用命令查看所有已安装应用: ```bash adb shell pm list packages -f | grep "应用关键字" ``` 2. **提取并修改AndroidManifest.xml** - 导出APK文件: ```bash adb pull $(adb shell pm path 包名 | cut -d: -f2) base.apk ``` - 使用APKTool反编译APK,定位`<application>`标签中的`android:persistent="true"`属性,改为false后重新打包 3. **覆盖系统应用(需root)** ```bash adb root adb remount adb push modified.apk /system/app/原应用目录/ adb reboot ``` **替代方案(无需root):** ```bash # 通过禁用应用组件间接实现 adb shell pm disable 包名 # 或强制停止应用 adb shell am force-stop 包名 ``` **注意事项:** - 系统级应用修改需要解锁Bootloader和root权限[^3][^4] - 直接修改系统APK可能导致系统不稳定 - Android 10及以上版本因分区限制需使用`adb remount -R`挂载[^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值