在Android系統中,一個Activity對應一個應用程序窗口,任何一個Activity的啓動都是由AMS服務和應用程序進程相互配合來完成的。AMS服務統一調度系統中全部進程的Activity啓動,而每一個Activity的啓動過程則由其所屬進程來完成。AMS服務經過realStartActivityLocked函數來通知應用程序進程啓動某個Activity:html
frameworks\base\services\java\com\android\server\am\ ActivityStack.javajava
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
|
final
boolean
realStartActivityLocked(ActivityRecord r,
ProcessRecord app,
boolean
andResume,
boolean
checkConfig)
throws
RemoteException {
...
//系統參數發送變化,通知Activity
if
(checkConfig) {
①Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(mService.mConfiguration,
r.mayFreezeScreenLocked(app) ? r.appToken :
null
);
mService.updateConfigurationLocked(config, r,
false
,
false
);
}
//將進程描述符設置到啓動的Activity描述符中
r.app = app;
app.waitingToKill =
null
;
//將啓動的Activity添加到進程啓動的Activity列表中
int
idx = app.activities.indexOf(r);
if
(idx <
0
) {
app.activities.add(r);
}
mService.updateLruProcessLocked(app,
true
,
true
);
try
{
...
//通知應用程序進程加載Activity
②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) {
...
}
if
(mMainStack) {
mService.startSetupActivityLocked();
}
return
true
;
}
|
AMS經過realStartActivityLocked函數來調度應用程序進程啓動一個Activity,參數r爲即將啓動的Activity在AMS服務中的描述符,參數app爲Activity運行所在的應用程序進程在AMS服務中的描述符。函數經過IApplicationThread代理對象ApplicationThreadProxy通知應用程序進程啓動r對應的Activity,應用程序進程完成Activity的加載等準備工做後,AMS最後啓動該Activity。啓動Activity的建立等工做是在應用程序進程中完成的,AMS是經過IApplicationThread接口和應用程序進程通訊的。r.appToken 在AMS服務端的類型爲Token,是IApplicationToken的Binder本地對象。android
frameworks\base\core\java\android\app\ ActivityThread.javaapp
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
|
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) {
//將AMS服務傳過來的參數封裝爲ActivityClientRecord對象
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);
//使用異步消息方式實現Activity的啓動
queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
}
</intent></resultinfo>
|
參數token從AMS服務端通過Binder傳輸到應用程序進程後,變爲IApplicationToken的Binder代理對象,類型爲IApplicationToken.Proxy,這是由於AMS和應用程序運行在不一樣的進程中。less
經過queueOrSendMessage函數將Binder跨進程調用轉換爲應用程序進程中的異步消息處理異步
frameworks\base\core\java\android\app\ ActivityThread.javaide
1
2
3
4
5
6
7
8
9
10
11
12
13
|
private
class
H
extends
Handler {
public
void
handleMessage(Message msg) {
switch
(msg.what) {
case
LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"activityStart"
);
ActivityClientRecord r = (ActivityClientRecord)msg.obj;
r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r,
null
);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
break
;
}
}
}
|
LAUNCH_ACTIVITY消息在應用程序主線程消息循環中獲得處理,應用程序經過handleLaunchActivity函數來啓動Activity。到此AMS服務就完成了Activity的調度任務,將Activity的啓動過程徹底交給了應用程序進程來完成。函數
frameworks\base\core\java\android\app\ ActivityThread.java佈局
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
private
void
handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//主線程空閒時會定時執行垃圾回收,主線程當前要完成啓動Activity的任務,所以這裏先暫停GC
unscheduleGcIdler();
if
(r.profileFd !=
null
) {
mProfiler.setProfiler(r.profileFile, r.profileFd);
mProfiler.startProfiling();
mProfiler.autoStopProfiler = r.autoStopProfiler;
}
// Make sure we are running with the most recent config.
①handleConfigurationChanged(
null
,
null
);
//建立Activity
②Activity a = performLaunchActivity(r, customIntent);
if
(a !=
null
) {
r.createdConfig =
new
Configuration(mConfiguration);
Bundle oldState = r.state;
//啓動Activity
③handleResumeActivity(r.token,
false
, r.isForward);
...
}
else
{
...
}
}
|
應用程序進程經過performLaunchActivity函數將即將要啓動的Activity加載到當前進程空間來,同時爲啓動Activity作準備。post
frameworks\base\core\java\android\app\ ActivityThread.java
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
56
57
58
59
60
61
62
|
private
Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if
(r.packageInfo ==
null
) {
//經過Activity所在的應用程序信息及該Activity對應的CompatibilityInfo信息從PMS服務中查詢當前Activity的包信息
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE);
}
//獲取當前Activity的組件信息
ComponentName component = r.intent.getComponent();
if
(component ==
null
) {
component = r.intent.resolveActivity(mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if
(r.activityInfo.targetActivity !=
null
) {
//packageName爲啓動Activity的包名,targetActivity爲Activity的類名
component =
new
ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
//經過類反射方式加載即將啓動的Activity
Activity activity =
null
;
try
{
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
①activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
if
(r.state !=
null
) {
r.state.setClassLoader(cl);
}
}
catch
(Exception e) {
...
}
try
{
//經過單例模式爲應用程序進程建立Application對象
②Application app = r.packageInfo.makeApplication(
false
, mInstrumentation);
if
(activity !=
null
) {
//爲當前Activity建立上下文對象ContextImpl
ContextImpl appContext =
new
ContextImpl();
//上下文初始化
③appContext.init(r.packageInfo, r.token,
this
);
appContext.setOuterContext(activity);
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
...
Configuration config =
new
Configuration(mCompatConfiguration);
//將當前啓動的Activity和上下文ContextImpl、Application綁定
④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保存到ActivityClientRecord中,ActivityClientRecord爲Activity在應用程序進程中的描述符
r.activity = activity;
...
}
r.paused =
true
;
//ActivityThread的成員變量mActivities保存了當前應用程序進程中的全部Activity的描述符
mActivities.put(r.token, r);
}
catch
(SuperNotCalledException e) {
...
}
return
activity;
}
|
在該函數中,首先經過PMS服務查找到即將啓動的Activity的包名信息,而後經過類反射方式建立一個該Activity實例,同時爲應用程序啓動的每個Activity建立一個LoadedApk實例對象,應用程序進程中建立的全部LoadedApk對象保存在ActivityThread的成員變量mPackages中。接着經過LoadedApk對象的makeApplication函數,使用單例模式建立Application對象,所以在android應用程序進程中有且只有一個Application實例。而後爲當前啓動的Activity建立一個ContextImpl上下文對象,並初始化該上下文,到此咱們能夠知道,啓動一個Activity須要如下對象:
1) XXActivity對象,須要啓動的Activity;
2) LoadedApk對象,每一個啓動的Activity都擁有屬於自身的LoadedApk對象;
3) ContextImpl對象,每一個啓動的Activity都擁有屬於自身的ContextImpl對象;
4) Application對象,應用程序進程中有且只有一個實例,和Activity是一對多的關係;
1
2
3
4
5
6
|
public
Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws
InstantiationException, IllegalAccessException,
ClassNotFoundException {
return
(Activity)cl.loadClass(className).newInstance();
}
|
這裏經過類反射的方式來加載要啓動的Activity實例對象。
首先介紹一下LoadedApk對象的構造過程:
frameworks\base\core\java\android\app\ ActivityThread.java
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
|
public
final
LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
int
flags) {
synchronized
(mPackages) {
//經過Activity的包名從對應的成員變量中查找LoadedApk對象
WeakReference<loadedapk> ref;
if
((flags&Context.CONTEXT_INCLUDE_CODE) !=
0
) {
ref = mPackages.get(packageName);
}
else
{
ref = mResourcePackages.get(packageName);
}
LoadedApk packageInfo = ref !=
null
? ref.get() :
null
;
if
(packageInfo !=
null
&& (packageInfo.mResources ==
null
|| packageInfo.mResources.getAssets().isUpToDate())) {
...
return
packageInfo;
}
}
//若是沒有,則爲當前Activity建立對應的LoadedApk對象
ApplicationInfo ai =
null
;
try
{
//經過包名在PMS服務中查找應用程序信息
ai = getPackageManager().getApplicationInfo(packageName,
PackageManager.GET_SHARED_LIBRARY_FILES, UserId.myUserId());
}
catch
(RemoteException e) {
// Ignore
}
//使用另外一個重載函數建立LoadedApk對象
if
(ai !=
null
) {
return
getPackageInfo(ai, compatInfo, flags);
}
return
null
;
}
</loadedapk>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public
final
LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
int
flags) {
boolean
includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) !=
0
;
boolean
securityViolation = includeCode && ai.uid !=
0
&& ai.uid != Process.SYSTEM_UID && (mBoundApplication !=
null
? !UserId.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
:
true
);
if
((flags&(Context.CONTEXT_INCLUDE_CODE|Context.CONTEXT_IGNORE_SECURITY))
== Context.CONTEXT_INCLUDE_CODE) {
...
}
return
getPackageInfo(ai, compatInfo,
null
, securityViolation, includeCode);
}
|
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
|
private
LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader,
boolean
securityViolation,
boolean
includeCode) {
//再次從對應的成員變量中查找LoadedApk實例
synchronized
(mPackages) {
WeakReference<loadedapk> ref;
if
(includeCode) {
ref = mPackages.get(aInfo.packageName);
}
else
{
ref = mResourcePackages.get(aInfo.packageName);
}
LoadedApk packageInfo = ref !=
null
? ref.get() :
null
;
if
(packageInfo ==
null
|| (packageInfo.mResources !=
null
&& !packageInfo.mResources.getAssets().isUpToDate())) {
...
//構造一個LoadedApk對象
packageInfo =
new
LoadedApk(
this
, aInfo, compatInfo,
this
, baseLoader,
securityViolation, includeCode &&
(aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) !=
0
);
//保存LoadedApk實例到ActivityThread的相應成員變量中
if
(includeCode) {
mPackages.put(aInfo.packageName,
new
WeakReference<loadedapk>(packageInfo));
}
else
{
mResourcePackages.put(aInfo.packageName,
new
WeakReference<loadedapk>(packageInfo));
}
}
return
packageInfo;
}
}
</loadedapk></loadedapk></loadedapk>
|
frameworks\base\core\java\android\app\LoadedApk.java
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
|
public
LoadedApk(ActivityThread activityThread, ApplicationInfo aInfo,
CompatibilityInfo compatInfo,
ActivityThread mainThread, ClassLoader baseLoader,
boolean
securityViolation,
boolean
includeCode) {
mActivityThread = activityThread;
mApplicationInfo = aInfo;
mPackageName = aInfo.packageName;
mAppDir = aInfo.sourceDir;
final
int
myUid = Process.myUid();
mResDir = aInfo.uid == myUid ? aInfo.sourceDir
: aInfo.publicSourceDir;
if
(!UserId.isSameUser(aInfo.uid, myUid) && !Process.isIsolated()) {
aInfo.dataDir = PackageManager.getDataDirForUser(UserId.getUserId(myUid),
mPackageName);
}
mSharedLibraries = aInfo.sharedLibraryFiles;
mDataDir = aInfo.dataDir;
mDataDirFile = mDataDir !=
null
?
new
File(mDataDir) :
null
;
mLibDir = aInfo.nativeLibraryDir;
mBaseClassLoader = baseLoader;
mSecurityViolation = securityViolation;
mIncludeCode = includeCode;
mCompatibilityInfo.set(compatInfo);
if
(mAppDir ==
null
) {
//爲應用程序進程建立一個ContextImpl上下文
if
(ActivityThread.mSystemContext ==
null
) {
ActivityThread.mSystemContext =
ContextImpl.createSystemContext(mainThread);
ActivityThread.mSystemContext.getResources().updateConfiguration(
mainThread.getConfiguration(),
mainThread.getDisplayMetricsLocked(compatInfo,
false
),
compatInfo);
}
mClassLoader = ActivityThread.mSystemContext.getClassLoader();
mResources = ActivityThread.mSystemContext.getResources();
}
}
|
從以上LoadedApk的構造函數能夠看出,LoadedApk類記錄了Activity運行所在的ActivityThread、Activity所在的應用程序信息、Activity的包名、Activity的資源路徑、Activity的庫路徑、Activity的數據存儲路徑、類加載器和應用程序所使用的資源等信息。
當Activity爲應用程序進程啓動的第一個Activity,所以須要構造一個Application對象
frameworks\base\core\java\android\app\LoadedApk.java
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
|
public
Application makeApplication(
boolean
forceDefaultAppClass,
Instrumentation instrumentation) {
//在應用程序進程空間以單例模式建立Application對象
if
(mApplication !=
null
) {
return
mApplication;
}
Application app =
null
;
//獲得應用程序的Application類名
String appClass = mApplicationInfo.className;
//若是應用程序沒用重寫Application,則使用Android默認的Application類
if
(forceDefaultAppClass || (appClass ==
null
)) {
appClass =
"android.app.Application"
;
}
try
{
java.lang.ClassLoader cl = getClassLoader();
//爲Application實例建立一個上下文對象ContextImpl
①ContextImpl appContext =
new
ContextImpl();
//初始化上下文
②appContext.init(
this
,
null
, mActivityThread);
//建立Application實例對象
③app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
}
catch
(Exception e) {
...
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
if
(instrumentation !=
null
) {
try
{
//調用Application的OnCreate函數
④instrumentation.callApplicationOnCreate(app);
}
catch
(Exception e) {
...
}
}
return
app;
}
|
在應用程序開發過程當中,當咱們重寫了Application類後,應用程序加載運行的是咱們定義的Application類,不然就加載運行默認的Application類。從Application對象的構造過程就能夠解釋爲何應用程序啓動後首先執行的是Application的OnCreate函數。在實例化Application對象時,一樣建立並初始化了一個ContextImpl上下文對象。
前面咱們介紹了,每個Activity擁有一個上下文對象ContextImpl,每個Application對象也擁有一個ContextImpl上下文對象,那麼ContextImpl對象又是如何構造的呢?
frameworks\base\core\java\android\app\ ContextImpl.java
1
2
3
|
ContextImpl() {
mOuterContext =
this
;
}
|
ContextImpl的構造過程什麼也沒幹,經過調用ContextImpl的init函數進行初始化
1
2
3
|
final
void
init(LoadedApk packageInfo,IBinder activityToken, ActivityThread mainThread) {
init(packageInfo, activityToken, mainThread,
null
,
null
);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
final
void
init(LoadedApk packageInfo,IBinder activityToken, ActivityThread mainThread,
Resources container, String basePackageName) {
mPackageInfo = packageInfo;
|