android persistent屬性研究

來源:互聯網
上載者:User

 原文

http://www.2cto.com/kf/201202/118540.html

為什麼寫這篇文章呢?前段時間在研究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的應用。
 
 
 
[c-sharp] www.2cto.com
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修飾的應用此時並未啟動並執行話,那麼AM將調用startProcessLocked啟動該app,關於startProcessLocked不再描述,另外一篇文章《How to start a new process for Android?》中做了詳細的介紹。
 
 
 
    app的啟動過程就是啟動app所在的package對應的進程。
 
 
 
  
[c-sharp] www.2cto.com
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對應的進程啟動完成之後,app是如何被create的。
 
 
 
    從文章《How to start a new process for Android?》中可知,zygote在建立新的進程均會啟動它的mainThread android.app.ActivityThread,因此我們從ActivityThread的main函數中接著分析app的create過程。
 
    在main中有下面這個操作
 
[c-sharp] www.2cto.com
thread.attach(false); 
 
 
 
    在attach過程中,ActivityThread會將對應的application attach到AM中去,交與AM去管理。這裡需要注意一個變數
 
[c-sharp] www.2cto.com
final ApplicationThread mAppThread = new ApplicationThread(); 
 
 
 
    mAppThread是一個ApplicationThread對象,mAppThread可以看作是當前進程主線程的核心,它負責處理本進程與其他進程(主要是AM)之間的通訊,同時通過attachApplication將mAppThread的代理Binder傳遞給AM。
 
[c-sharp] www.2cto.com
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調用AM的attachApplication過程再往下看。
    在該過程中,AM調用到了IPC通訊調用mAppThread的bindApplication;
 
 
 
 
[c-sharp]
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發送BIND_APPLICATION訊息。下面看看ActivityThread自身維護的handler對訊息BIND_APPLICATION的處理,最終會調用到handleBindApplication函數
    你會發現在handleBindApplication函數中有這麼一句
 
 
[c-sharp] www.2cto.com
mInstrumentation.callApplicationOnCreate(app); 
    
    我們最終在繞了好大一圈之後,調用了app的onCreate函數來啟動這個application
 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

Tags Index: