android:persistent属性
為什么寫這篇文章呢?前段時間在研究telephony時,一直沒有在framework下發(fā)現(xiàn)對telephony的初始化(PhoneFactory.java中的makeDefaultPhones函數(shù))的調(diào)用。結(jié)果全局搜索之后發(fā)現(xiàn)在application PhoneApp(packages/apps/Phone)中調(diào)用了。但是application PhoneApp既沒有被Broadcast喚醒,也沒有被其他service調(diào)用,那么是android是通過什么方式來啟動PhoneApp,所以就發(fā)現(xiàn)了屬性android:persistent。
?
??? 在AndroidManifest.xml定義中,application有這么一個屬性android:persistent,根據(jù)字面意思來理解就是說該應(yīng)用是可持久的,也即是常駐的應(yīng)用。其實就是這么個理解,被android:persistent修飾的應(yīng)用會在系統(tǒng)啟動之后被AM啟動。
?
??? AM首先去PM(PackageManagerService)中去查找設(shè)置了android:persistent的應(yīng)用。
?
[c-sharp] view plaincopyprint?public void systemReady(final Runnable goingCallback) {if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {try {List apps = AppGlobals.getPackageManager().getPersistentApplications(STOCK_PM_FLAGS);if (apps != null) {int N = apps.size();int i;for (i=0; i<N; i++) {ApplicationInfo info= (ApplicationInfo)apps.get(i);if (info != null &&!info.packageName.equals("android")) {addAppLocked(info);}}}} catch (RemoteException ex) {// pm is in same process, this will never happen.}} }
?
??? 假如該被android:persistent修飾的應(yīng)用此時并未運行的話,那么AM將調(diào)用startProcessLocked啟動該app,關(guān)于startProcessLocked不再描述,另外一篇文章《How to start a new process for Android?》中做了詳細的介紹。
?
??? app的啟動過程就是啟動app所在的package對應(yīng)的進程。
?
???
[c-sharp] view plaincopyprint?final ProcessRecord addAppLocked(ApplicationInfo info) {ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);if (app == null) {app = newProcessRecordLocked(null, info, null);mProcessNames.put(info.processName, info.uid, app);updateLruProcessLocked(app, true, true);}if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))== (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {app.persistent = true;app.maxAdj = CORE_SERVER_ADJ;}if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {mPersistentStartingProcesses.add(app);startProcessLocked(app, "added application", app.processName);}return app;}
?
??? 下面介紹app所在的package對應(yīng)的進程啟動完成之后,app是如何被create的。
?
??? 從文章《How to start a new process for Android?》中可知,zygote在創(chuàng)建新的進程均會啟動它的mainThread android.app.ActivityThread,因此我們從ActivityThread的main函數(shù)中接著分析app的create過程。
??? 在main中有下面這個操作
[c-sharp] view plaincopyprint?thread.attach(false);
?
??? 在attach過程中,ActivityThread會將對應(yīng)的application attach到AM中去,交與AM去管理。這里需要注意一個變量
[c-sharp] view plaincopyprint?final ApplicationThread mAppThread = new ApplicationThread();
?
??? mAppThread是一個ApplicationThread對象,mAppThread可以看作是當(dāng)前進程主線程的核心,它負責(zé)處理本進程與其他進程(主要是AM)之間的通信,同時通過attachApplication將mAppThread的代理Binder傳遞給AM。
[c-sharp] view plaincopyprint?private final void attach(boolean system) {sThreadLocal.set(this);mSystemThread = system;if (!system) {ViewRoot.addFirstDrawHandler(new Runnable() {public void run() {ensureJitEnabled();}});android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");RuntimeInit.setApplicationObject(mAppThread.asBinder());IActivityManager mgr = ActivityManagerNative.getDefault();try {mgr.attachApplication(mAppThread);} catch (RemoteException ex) {}}}
?
?
??? 上面的attach代碼中,我們順著IPC調(diào)用AM的attachApplication過程再往下看。
??? 在該過程中,AM調(diào)用到了IPC通信調(diào)用mAppThread的bindApplication;
?
?
[c-sharp] view plaincopyprint?private final boolean attachApplicationLocked(IApplicationThread thread,int pid) {thread.bindApplication(processName, app.instrumentationInfo != null? app.instrumentationInfo : app.info, providers,app.instrumentationClass, app.instrumentationProfileFile,app.instrumentationArguments, app.instrumentationWatcher, testMode, isRestrictedBackupMode || !normalMode,mConfiguration, getCommonServicesLocked());updateLruProcessLocked(app, false, true);app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); }
?
??? mAppThread的bindApplication再通過消息機制向ActivityThread自身維護的handler發(fā)送BIND_APPLICATION消息。下面看看ActivityThread自身維護的handler對消息BIND_APPLICATION的處理,最終會調(diào)用到handleBindApplication函數(shù)
??? 你會發(fā)現(xiàn)在handleBindApplication函數(shù)中有這么一句
mInstrumentation.callApplicationOnCreate(app); ????
??? 我們最終在繞了好大一圈之后,調(diào)用了app的onCreate函數(shù)來啟動這個application
?
總結(jié)
以上是生活随笔為你收集整理的android:persistent属性的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android中对Log日志文件的分析
- 下一篇: drawable(hdpi,ldpi,m