您的位置:首页 > 其它

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

2017-05-22 17:41 525 查看
本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接

本系列博客将详细阐述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. 新进程启动ActivityThread

5. 应用进程绑定到ActivityManagerService

6. ActivityThread的Handler处理启动Activity的消息

4. 新进程启动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

点击图片可看大图





在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的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的调度算法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: