国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

深入理解Activity啟動流程(三)–Activity啟動的詳細流程2

2019-11-08 00:00:40
字體:
來源:轉載
供稿:網友

本系列博客將詳細闡述Activity的啟動流程,這些博客基于Cm 10.1源碼研究。

深入理解Activity啟動流程(一)--Activity啟動的概要流程深入理解Activity啟動流程(二)--Activity啟動相關類的類圖深入理解Activity啟動流程(三)--Activity啟動的詳細流程1深入理解Activity啟動流程(四)--Activity Task的調度算法

上篇博客介紹了Activity詳細啟動流程的前半部分:

1. Activity調用ActivityManagerService啟動應用2. ActivityManagerService調用Zygote孵化應用進程3. Zygote孵化應用進程

本篇博客主要介紹Activity詳細啟動流程的后半部分:

4. 新進程啟動ActivityThread5. 應用進程綁定到ActivityManagerService6. ActivityThread的Handler處理啟動Activity的消息

4. 新進程啟動ActivityThread

點擊圖片可看大圖

zygote_activitythread

Zygote進程孵化出新的應用進程后,會執行ActivityThread類的main方法。在該方法里會先準備好Looper和消息隊列,然后調用attach方法將應用進程綁定到ActivityManagerService,然后進入loop循環,不斷地讀取消息隊列里的消息,并分發消息。

12345678910111213141516
//ActivityThread類public static void main(String[] args) {    //...     Looper.PRepareMainLooper();    ActivityThread thread = new ActivityThread();    thread.attach(false);    if (sMainThreadHandler == null) {        sMainThreadHandler = thread.getHandler();    }    AsyncTask.init();    //...    Looper.loop();    //...}

5. 應用進程綁定到ActivityManagerService

點擊圖片可看大圖

application_amservice

在ActivityThread的main方法里調用thread.attach(false);attach方法的主要代碼如下所示:

123456789101112131415161718192021
//ActivityThread類private void attach(boolean system) {    sThreadLocal.set(this);    mSystemThread = system;    if (!system) {        //...        IActivityManager mgr = ActivityManagerNative.getDefault();        try {        //調用ActivityManagerService的attachapplication方法        //將ApplicationThread對象綁定至ActivityManagerService,        //這樣ActivityManagerService就可以        //通過ApplicationThread代理對象控制應用進程            mgr.attachApplication(mAPPThread);        } catch (RemoteException ex) {            // Ignore        }    } else {        //...    }    //... }

ActivityManagerService的attachApplication方法執行attachApplicationLocked(thread, callingPid)進行綁定。

1234567891011121314151617181920212223242526272829303132333435363738394041
//ActivityManagerService類private final boolean attachApplicationLocked(IApplicationThread thread,        int pid) {     ProcessRecord app;    //...         app.thread = thread;     //...      try {        //...        thread.bindApplication(processName, appInfo, providers,                app.instrumentationClass, profileFile, profileFd, profileAutoStop,                app.instrumentationArguments, app.instrumentationWatcher, testMode,                enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,                new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),                mCoreSettingsObserver.getCoreSettingsLocked());        //...     } catch (Exception e) {       //...    }    //...     ActivityRecord hr = mMainStack.topRunningActivityLocked(null);    if (hr != null && normalMode) {        if (hr.app == null && app.uid == hr.info.applicationInfo.uid                && processName.equals(hr.processName)) {            try {                if (mHeadless) {                    Slog.e(TAG, "Starting activities not supported on headless device: " + hr);                } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {                //mMainStack.realStartActivityLocked真正啟動activity                    didSomething = true;                }            } catch (Exception e) {                //...            }        } else {            //...        }    }    //...     return true;}

attachApplicationLocked方法有兩個重要的函數調用thread.bindApplication和mMainStack.realStartActivityLocked。thread.bindApplication將應用進程的ApplicationThread對象綁定到ActivityManagerService,也就是說獲得ApplicationThread對象的代理對象。mMainStack.realStartActivityLocked通知應用進程啟動Activity。

5.1 thread.bindApplication

thread對象其實是ActivityThread里ApplicationThread對象在ActivityManagerService的代理對象,故此執行thread.bindApplication,最終會調用ApplicationThread的bindApplication方法,該方法的主要代碼如下所示:

12345678910111213141516171819202122232425262728
//ActivityThread類public final void bindApplication(String processName,        ApplicationInfo appInfo, List<ProviderInfo> providers,        ComponentName instrumentationName, String profileFile,        ParcelFileDescriptor profileFd, boolean autoStopProfiler,        Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,        int debugMode, boolean enableOpenGlTrace, boolean isRestrictedBackupMode,        boolean persistent, Configuration config, CompatibilityInfo compatInfo,        Map<String, IBinder> services, Bundle coreSettings) {    //...      AppBindData data = new AppBindData();    data.processName = processName;    data.appInfo = appInfo;    data.providers = providers;    data.instrumentationName = instrumentationName;    data.instrumentationArgs = instrumentationArgs;    data.instrumentationWatcher = instrumentationWatcher;    data.debugMode = debugMode;    data.enableOpenGlTrace = enableOpenGlTrace;    data.restrictedBackupMode = isRestrictedBackupMode;    data.persistent = persistent;    data.config = config;    data.compatInfo = compatInfo;    data.initProfileFile = profileFile;    data.initProfileFd = profileFd;    data.initAutoStopProfiler = false;    queueOrSendMessage(H.BIND_APPLICATION, data);}

這樣調用queueOrSendMessage會往ActivityThread的消息隊列發送消息,消息的用途是BIND_APPLICATION。

這樣會在handler里處理BIND_APPLICATION消息,接著調用handleBindApplication方法處理綁定消息。

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
//ActivityThread類private void handleBindApplication(AppBindData data) {  //...    ApplicationInfo instrApp = new ApplicationInfo();  instrApp.packageName = ii.packageName;  instrApp.sourceDir = ii.sourceDir;  instrApp.publicSourceDir = ii.publicSourceDir;  instrApp.dataDir = ii.dataDir;  instrApp.nativeLibraryDir = ii.nativeLibraryDir;  LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,        appContext.getClassLoader(), false, true);  ContextImpl instrContext = new ContextImpl();  instrContext.init(pi, null, this);    //...           if (data.instrumentationName != null) {       //...  } else {       //注意Activity的所有生命周期方法都會被Instrumentation對象所監控,       //也就說執行Activity的生命周期方法前后一定會調用Instrumentation對象的相關方法       //并不是說只有跑單測用例才會建立Instrumentation對象,       //即使不跑單測也會建立Instrumentation對象       mInstrumentation = new Instrumentation();  }  //...   try {     //...     Application app = data.info.makeApplication(data.restrictedBackupMode, null);     mInitialApplication = app;     //...              try {          mInstrumentation.onCreate(data.instrumentationArgs);      }catch (Exception e) {             //...      }      try {           //這里會調用Application的onCreate方法           //故此Applcation對象的onCreate方法會比ActivityThread的main方法后調用           //但是會比這個應用的所有activity先調用            mInstrumentation.callApplicationOnCreate(app);        } catch (Exception e) {           //...        }    } finally {        StrictMode.setThreadPolicy(savedPolicy);    }}

5.2 mMainStack.realStartActivityLocked

realStartActivity會調用scheduleLaunchActivity啟動activity,主要代碼:

1234567891011121314151617181920212223
//ActivityStack類final boolean realStartActivityLocked(ActivityRecord r,        ProcessRecord app, boolean andResume, boolean checkConfig)        throws RemoteException {    //...      try {        //...        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,                System.identityHashCode(r), r.info,                new Configuration(mService.mConfiguration),                r.compat, r.icicle, results, newIntents, !andResume,                mService.isNextTransitionForward(), profileFile, profileFd,                profileAutoStop);                //...            } catch (RemoteException e) {        //...    }    //...        return true;}

同樣app.thread也只是ApplicationThread對象在ActivityManagerService的一個代理對象而已,最終會調用ApplicationThread的scheduleLaunchActivity方法。

1234567891011121314151617181920212223
//ActivityThread類public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,        ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,        Bundle state, List<ResultInfo> pendingResults,        List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,        String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {    ActivityClientRecord r = new ActivityClientRecord();    r.token = token;    r.ident = ident;    r.intent = intent;    r.activityInfo = info;    r.compatInfo = compatInfo;    r.state = state;    r.pendingResults = pendingResults;    r.pendingIntents = pendingNewIntents;    r.startsNotResumed = notResumed;    r.isForward = isForward;    r.profileFile = profileName;    r.profileFd = profileFd;    r.autoStopProfiler = autoStopProfiler;    updatePendingConfiguration(curConfig);    queueOrSendMessage(H.LAUNCH_ACTIVITY, r);}

這里調用了queueOrSendMessage往ActivityThread的消息隊列發送了消息,消息的用途是啟動Activity,接下來ActivityThread的handler便會處理該消息。

6. ActivityThread的Handler處理啟動Activity的消息

點擊圖片可看大圖

activitythread_activity

ActivityThread的handler調用handleLaunchActivity處理啟動Activity的消息,handleLaunchActivity的主要代碼如下所示:

12345678910111213
//ActivityThread類private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {    //...     Activity a = performLaunchActivity(r, customIntent);    if (a != null) {        //...        handleResumeActivity(r.token, false, r.isForward,                !r.activity.mFinished && !r.startsNotResumed);        //...    } else {        //...    }}

handleLaunchActivity方法里有有兩個重要的函數調用,performLaunchActivity和handleResumeActivity,performLaunchActivity會調用Activity的onCreate,onStart,onResotreInstanceState方法,handleResumeActivity會調用Activity的onResume方法.

6.1 performLaunchActivity

performLaunchActivity的主要代碼如下所示:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
//ActivityThread類private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {    //...    Activity activity = null;    try {        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();        activity = mInstrumentation.newActivity(                cl, component.getClassName(), r.intent);        //...    } catch (Exception e) {        //...    }    try {        //r.packageInfo.makeApplication實際并未創建Application對象,        //因為bindApplication過程已經創建了Application對象,        //makeApplication方法會返回已創建的Application對象        Application app = r.packageInfo.makeApplication(false, mInstrumentation);        //...                 if (activity != null) {            //...            //將application對象,appContext對象綁定到新建的activity對象            activity.attach(appContext, this, getInstrumentation(), r.token,                    r.ident, app, r.intent, r.activityInfo, title, r.parent,                    r.embeddedID, r.lastNonConfigurationInstances, config);            //...             //會調用Activity的onCreate方法                         mInstrumentation.callActivityOnCreate(activity, r.state);            //...            //...            //調用Activity的onStart方法            if (!r.activity.mFinished) {                activity.performStart();                r.stopped = false;            }                          if (!r.activity.mFinished) {                if (r.state != null) {                    //會調用Activity的onRestoreInstanceState方法                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);                }            }            if (!r.activity.mFinished) {                activity.mCalled = false;                mInstrumentation.callActivityOnPostCreate(activity, r.state);                //...            }        }        //...    } catch (SuperNotCalledException e) {        throw e;    } catch (Exception e) {        //...    }    return activity;}

6.2 handleResumeActivity

handleResumeActivity的主要代碼如下所示:

123456789101112131415161718192021222324252627282930313233343536373839
//ActivityThread類final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,        boolean reallyResume) {    //...    //performResumeActivity最終會調用Activity的onResume方法     ActivityClientRecord r = performResumeActivity(token, clearHide);    if (r != null) {        final Activity a = r.activity;        //...         //顯示界面        if (r.window == null && !a.mFinished && willBeVisible) {            r.window = r.activity.getWindow();            View decor = r.window.getDecorView();            decor.setVisibility(View.INVISIBLE);            ViewManager wm = a.getWindowManager();            WindowManager.LayoutParams l = r.window.getAttributes();            a.mDecor = decor;            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;            l.softInputMode |= forwardBit;            if (a.mVisibleFromClient) {                a.mWindowAdded = true;                wm.addView(decor, l);            }           //...                 } else if (!willBeVisible) {             //...        }        // Tell the activity manager we have resumed.        if (reallyResume) {            try {                ActivityManagerNative.getDefault().activityResumed(token);            } catch (RemoteException ex) {            }        }    } else {         //...    }}

performResumeActivity的主要代碼如下所示:

123456789101112131415161718
//ActivityThread類public final ActivityClientRecord performResumeActivity(IBinder token,        boolean clearHide) {    ActivityClientRecord r = mActivities.get(token);    //...    if (r != null && !r.activity.mFinished) {         //...        try {            //...             //會調用Activity的onResume方法             r.activity.performResume();            //...        } catch (Exception e) {            //...        }    }    return r;}

總結

Activity的概要啟動流程:

用戶在Launcher程序里點擊應用圖標時,會通知ActivityManagerService啟動應用的入口Activity,ActivityManagerService發現這個應用還未啟動,則會通知Zygote進程孵化出應用進程,然后在這個dalvik應用進程里執行ActivityThread的main方法。應用進程接下來通知ActivityManagerService應用進程已啟動,ActivityManagerService保存應用進程的一個代理對象,這樣ActivityManagerService可以通過這個代理對象控制應用進程,然后ActivityManagerService通知應用進程創建入口Activity的實例,并執行它的生命周期方法

現在也可以理解:

如果應用的組件(包括所有組件Activity,Service,ContentProvider,Receiver) 被啟動,肯定會先啟動以應用包名為進程名的進程,這些組件都會運行在應用包名為進程名的進程里,并且是在主線程里。應用進程啟動時會先創建Application對象,并執行Application對象的生命周期方法,然后才啟動應用的組件。

有一種情況比較特殊,那就是為組件設置了特殊的進程名,也就是說通過android:process設置進程名的情況,此時組件運行在單獨的進程內。

下篇博客將介紹Activity,Task的調度算法。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 光山县| 准格尔旗| 民和| 广元市| 融水| 博客| 郸城县| 晋城| 依安县| 蓬安县| 兴业县| 岳阳县| 方正县| 吴忠市| 汉川市| 毕节市| 台州市| 武川县| 尉氏县| 绥阳县| 徐水县| 西峡县| 贞丰县| 惠来县| 若尔盖县| 新晃| 桃园县| 墨江| 南江县| 苍山县| 大冶市| 阜阳市| 宁河县| 遵义县| 乌审旗| 调兵山市| 汉寿县| 牡丹江市| 奉新县| 德化县| 宿松县|