深入理解Activity启动流程(三)–Activity启动的详细流程2

本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接

本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究。

上篇博客介绍了Activity详细启动流程的前半部分:

  • 1. Activity调用ActivityManagerService启动应用
  • 2. ActivityManagerService调用Zygote孵化应用进程
  • 3. Zygote孵化应用进程

本篇博客主要介绍Activity详细启动流程的后半部分:

  • 4. 新进程启动ActivityThread
  • 5. 应用进程绑定到ActivityManagerService
  • 6. ActivityThread的Handler处理启动Activity的消息

4. 新进程启动ActivityThread

点击图片可看大图

zygote_activitythread

Zygote进程孵化出新的应用进程后,会执行ActivityThread类的main方法。在该方法里会先准备好Looper和消息队列,然后调用attach方法将应用进程绑定到ActivityManagerService,然后进入loop循环,不断地读取消息队列里的消息,并分发消息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//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方法的主要代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//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)进行绑定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//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方法,该方法的主要代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//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方法处理绑定消息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//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,主要代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//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方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//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的主要代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
//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的主要代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//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的主要代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//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的主要代码如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//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的调度算法。

转载于:https://www.cnblogs.com/ldq2016/p/6890554.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值