為什么要學(xué)習(xí)源碼?
這是源碼分析系列的第三篇博客了,這里我說明一下為什么要進(jìn)行Activity啟動(dòng)流程的源碼分析。
學(xué)習(xí)源碼有助于我們學(xué)習(xí)一些黑科技,比如學(xué)習(xí)插件化的從時(shí)候我們需要學(xué)習(xí)Hook機(jī)制,但是學(xué)習(xí)Hook機(jī)制的時(shí)候我們需要掌握Activity的啟動(dòng)流程、消息機(jī)制等等機(jī)制。
Activity啟動(dòng)流程分析
我們平常在Activity中調(diào)用startActivity(intent)來啟動(dòng)一個(gè)Activity的時(shí)候,通過調(diào)用鏈的分析,最終會(huì)調(diào)用Activity的startActivityForResult方法:
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
if (mParent == null) {
options = transferSpringboardActivityOptions(options);
//調(diào)用Instrumentation類的execStartActivity方法
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
//如果需要有結(jié)果返回的話,還需要去發(fā)送消息
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
這個(gè)方法實(shí)際會(huì)調(diào)用Instrumentation類的execStartActivity方法,Instrumentation類與Activity的初始化有關(guān)。Instrumentation類的execStartActivity方法如下:
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
//IApplicationThread是一個(gè)AIDL接口,實(shí)現(xiàn)類是ActivityThread里的內(nèi)部類ApplicationThread通過他可以進(jìn)行進(jìn)程間通信,通過ApplicationThread可以識(shí)別出一個(gè)進(jìn)程。
IApplicationThread whoThread = (IApplicationThread) contextThread;
//...省略一些代碼
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//ActivityManagerNative是一個(gè)AIDL接口的二分之一:Stub(存根)
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
}
ActivityManagerNative是一個(gè)AIDL接口的二分之一:Stub,與AMS進(jìn)行通信的。ActivityManagerNative里面還有一個(gè)內(nèi)部類ActivityManagerProxy。如下圖所示:
因此到這里已經(jīng)開始了進(jìn)程間通信了,通過通知AMS去進(jìn)行后續(xù)的處理。
之前已經(jīng)分析過了,通過ActivityManagerNative.getDefault()得到的實(shí)質(zhì)上是ActivityManagerNative與AMS進(jìn)行通信的一個(gè)AIDL接口的引用:
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
protected IActivityManager create() {
IBinder b = ServiceManager.getService("activity");
IActivityManager am = asInterface(b);
return am;
}
};
而實(shí)現(xiàn)這個(gè)接口的正是ActivityManagerNative的一個(gè)內(nèi)部類ActivityManagerProxy:
class ActivityManagerProxy implements IActivityManager{
}
那么這個(gè)ActivityManagerProxy就是向AMS的IBinder寫數(shù)據(jù)的,比如說啟動(dòng)Activity的時(shí)候就需要進(jìn)行進(jìn)程間通信了,我們把數(shù)據(jù)都放到可序列化的Parcel對(duì)象里面,寫到IBinder驅(qū)動(dòng)里面去。
下面是ActivityManagerProxy中startActivity的實(shí)現(xiàn):
//caller代表著應(yīng)用,調(diào)用者,比如說通過桌面啟動(dòng)Activity的話,caller就是代表著Launcher的描述。
public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
//這里省略一些寫數(shù)據(jù)的代碼
//調(diào)用transact方法向IBinder驅(qū)動(dòng)寫數(shù)據(jù)
mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
//讀取跨進(jìn)程通信的時(shí)候是否有異常
reply.readException();
int result = reply.readInt();
//回收數(shù)據(jù),防止內(nèi)存泄漏
reply.recycle();
data.recycle();
return result;
}
數(shù)據(jù)寫到Binder驅(qū)動(dòng)里面去之后就會(huì)回調(diào)ActivityManagerNative(也就是Stub)的onTransact方法,這個(gè)方法比較長(zhǎng),還包括很多其他的case,這里只抽取了一部分核心代碼。
根據(jù)我們transact的code(START_ACTIVITY_TRANSACTION),可以過濾出下面的代碼:
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
case START_ACTIVITY_TRANSACTION:
{
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
//將IBinder接口轉(zhuǎn)換為AIDL的引用
IApplicationThread app = ApplicationThreadNative.asInterface(b);
String callingPackage = data.readString();
//省略一些獲取參數(shù)的代碼
//ActivityManagerNative的真正實(shí)現(xiàn)類是AMS,因此這里是調(diào)用AMS的startActivity方法
int result = startActivity(app, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
reply.writeNoException();
reply.writeInt(result);
return true;
}
}
ActivityManagerNative的真正實(shí)現(xiàn)類是ActivityManagerService(AMS),AMS與四大組件的創(chuàng)建、傳播、生命周期的管理里面起到了重要的作用。
這里是調(diào)用了AMS的startActivity方法:
@Override
public final int startActivity(...省略一些參數(shù)) {
return startActivityAsUser(...省略一些參數(shù));
}
而AMS的startActivity里面又會(huì)調(diào)用startActivityAsUser方法:
@Override
public final int startActivityAsUser(...省略一些參數(shù)) {
//拿到啟動(dòng)的信息
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
//這里又會(huì)調(diào)用ActivityStarter的startActivityMayWait方法:
return mActivityStarter.startActivityMayWait(...省略一些參數(shù));
}
ActivityStackSupervisor是APP的棧的管理類,管理四大組件的棧的問題。而ActivityStarter就是每一個(gè)被管理的任務(wù)棧。分Task任務(wù)來管理,一個(gè)任務(wù)里面可能多個(gè)棧,別說當(dāng)前正在使用、已停止的棧、歷史棧。
ActivityStackSupervisor里面記錄了一大堆Activity的記錄:
final ArrayList<ActivityRecord> mStoppingActivities = new ArrayList<>();
final ArrayList<ActivityRecord> mFinishingActivities = new ArrayList<>();
這里又會(huì)調(diào)用ActivityStarter的startActivityMayWait方法:
final int startActivityMayWait(...省略一些參數(shù)) {
mSupervisor.mActivityMetricsLogger.notifyActivityLaunching();
boolean componentSpecified = intent.getComponent() != null;
//封裝出一個(gè)Intent來
intent = new Intent(intent);
//這里經(jīng)歷了一個(gè)PMS(PackageManagerService)對(duì)Intent的驗(yàn)證過程,驗(yàn)證這個(gè)Activity在清單文件里面是否有定義,這一步很重要,將來我們學(xué)習(xí)Hook機(jī)制免清單注冊(cè)啟動(dòng)Activity的時(shí)候這是比較關(guān)鍵的
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
//省略一些代碼
//把目標(biāo)的Activity的信息提取出來
ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
//省略一些代碼
synchronized (mService) {
//通過獲取Binder獲取我們啟動(dòng)這個(gè)Activity的進(jìn)程id,Uid
final int realCallingPid = Binder.getCallingPid();
final int realCallingUid = Binder.getCallingUid();
//省略一些代碼
final ActivityRecord[] outRecord = new ActivityRecord[1];
//繼續(xù)調(diào)用startActivityLocked方法:
int res = startActivityLocked(...省略一些參數(shù));
//省略一些代碼
}
}
上面的函數(shù)里面比較重要的就是下面這一行代碼:
ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
這里調(diào)用了ActivityStackSupervisor的resolveIntent,通過調(diào)用鏈分析得到實(shí)際上是調(diào)用了下面這個(gè)方法:
ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {
try {
return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,
PackageManager.MATCH_DEFAULT_ONLY | flags
| ActivityManagerService.STOCK_PM_FLAGS, userId);
} catch (RemoteException e) {
}
return null;
}
我們平時(shí)啟動(dòng)Activity的時(shí)候,如果要檢測(cè)有沒有對(duì)應(yīng)Activity的話,就需要resolveIntent方法。
這里PMS會(huì)去找清單文件,是否有注冊(cè)的Activity,尤其是隱式意圖啟動(dòng)Activity的時(shí)候。
下面我們看AppGlobals里面getPackageManager方法的定義,其返回的是IPackageManager,這是一個(gè)AIDL接口。
public static IPackageManager getPackageManager() {
return ActivityThread.getPackageManager();
}
下面看看ActivityThread里面的getPackageManager方法,實(shí)際上就是一個(gè)“叫服務(wù)”的過程,實(shí)際就是拿到IBinder引用,然后通過asInterface方法轉(zhuǎn)換為與PMS通信的AIDL接口的引用:
public static IPackageManager getPackageManager() {
IBinder b = ServiceManager.getService("package");
sPackageManager = IPackageManager.Stub.asInterface(b);
return sPackageManager;
}
整個(gè)過程就是拿到PackageManager的AIDL引用,然后調(diào)用他的resolveIntent方法,而這個(gè)IPackageManager的實(shí)現(xiàn)類就是誰呢?不是PackageManager,因?yàn)樗皇且粋€(gè)單獨(dú)的類:
public abstract class PackageManager {
}
IPackageManager的真正實(shí)現(xiàn)類是PackageManagerService(PMS),這是一個(gè)系統(tǒng)服務(wù):
public class PackageManagerService extends IPackageManager.Stub {
}
PackageManagerService里面的resolveIntent方法實(shí)現(xiàn)如下:
@Override
public ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId) {
try {
//省略一些代碼
//查找是否存在這個(gè)Intent代表的Activity,返回的結(jié)果可能有多個(gè)
final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
flags, userId);
//選擇最好(最符合條件)的一個(gè)Activity
final ResolveInfo bestChoice =
chooseBestActivity(intent, resolvedType, flags, query, userId);
return bestChoice;
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
PackageManagerService在Android系統(tǒng)啟動(dòng)的時(shí)候就會(huì)啟動(dòng),并且會(huì)掃描所有的已經(jīng)安裝的應(yīng)用的清單文件,然后保存到內(nèi)存當(dāng)中。這里調(diào)用了queryIntentActivitiesInternal方法去找符合Intent過濾條件的Activity列表。
該方法的實(shí)現(xiàn)如下:
private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, int userId) {
//省略一些代碼
//拿到Intent的Component
ComponentName comp = intent.getComponent();
//省略一些代碼
if (comp != null) {
final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1);
//通過組件名、flags、userId獲取Activity信息
final ActivityInfo ai = getActivityInfo(comp, flags, userId);
if (ai != null) {
final ResolveInfo ri = new ResolveInfo();
ri.activityInfo = ai;
//如果能夠找到對(duì)應(yīng)的Activity,就會(huì)添加到list里面去,最后返回
list.add(ri);
}
return list;
}
//后面省略一些Intent先后排序的代碼
return result;
}
在PackageManagerService里面的resolveIntent方法最后,還會(huì)考慮到Intent的優(yōu)先級(jí)問題,也就是調(diào)用chooseBestActivity,選擇最好的Activity:
- 如果查詢結(jié)果只有一個(gè)的話,那么直接返回第0個(gè);否則需要處理優(yōu)先級(jí)的問題。
- 否則如果我們只啟動(dòng)一個(gè)Activity的話,就要根據(jù)priority優(yōu)先級(jí)來判斷了。(所以清單文件里面有優(yōu)先級(jí)的配置)。
下面我們稍微研究一些關(guān)于PMS的chooseBestActivity方法:
private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
int flags, List<ResolveInfo> query, int userId) {
if (query != null) {
final int N = query.size();
//如果查詢結(jié)果只有一個(gè)的話,那么直接返回第0個(gè);否則需要處理優(yōu)先級(jí)的問題
if (N == 1) {
return query.get(0);
} else if (N > 1) {
ResolveInfo r0 = query.get(0);
ResolveInfo r1 = query.get(1);
//如果我們只啟動(dòng)一個(gè)Activity的話,就要根據(jù)priority優(yōu)先級(jí)來判斷了。(所以清單文件里面有優(yōu)先級(jí)的配置)
if (r0.priority != r1.priority
|| r0.preferredOrder != r1.preferredOrder
|| r0.isDefault != r1.isDefault) {
return query.get(0);
}
//省略一些代碼
}
}
return null;
}
也就是說這里系統(tǒng)通過PMS去做了一個(gè)驗(yàn)證,判斷清單文件里面是否有這個(gè)Activity,并且返回最好的一個(gè)。
PMS主要用來管理包的信息,而包的信息保存在清單文件。例如他回去/data/data目錄去掃描。例如在PMS構(gòu)造的時(shí)候你會(huì)發(fā)現(xiàn)這些代碼:
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
synchronized (mPackages) {
//需要掃描的目錄
File dataDir = Environment.getDataDirectory();
//data/data/app:第三方APP的安裝目錄
mAppInstallDir = new File(dataDir, "app");
mAppLib32InstallDir = new File(dataDir, "app-lib");
mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
mAsecInternalPath = new File(dataDir, "app-asec").getPath();
//data/data/app-private:系統(tǒng)APP的安裝目錄
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
if (!mOnlyCore) {
//調(diào)用scanDirLI去掃描
scanDirLI(mEphemeralInstallDir, mDefParseFlags
| PackageParser.PARSE_IS_EPHEMERAL,
scanFlags | SCAN_REQUIRE_KNOWN, 0);
}
}
}
PMS的scanDirLI方法如下:
private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
final File[] files = dir.listFiles();
for (File file : files) {
//掃描,判斷是不是APK文件
final boolean isPackage = (isApkFile(file) || file.isDirectory())
&& !PackageInstallerService.isStageName(file.getName());
if (!isPackage) {
continue;
}
try {
//然后去解析APK的清單文件,把四大組件的信息、權(quán)限等解析出來
scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
scanFlags, currentTime, null);
} catch (PackageManagerException e) {
}
}
}
一開機(jī)的時(shí)候,SystemServer啟動(dòng)之后就會(huì)啟動(dòng)PMS,就會(huì)調(diào)用PMS的main方法,把自己注冊(cè)到ServiceManager里面去:
ServiceManager就是我們的服務(wù)總臺(tái),保存所有服務(wù)的“聯(lián)系方式”。
public static PackageManagerService main(...省略一些參數(shù)) {
PackageManagerServiceCompilerMapping.checkProperties();
//new一個(gè)PMS,PMS在構(gòu)造方法的時(shí)候就會(huì)去掃描清單文件
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
m.enableSystemUserPackages();
//把自己注冊(cè)到ServiceManager里面去
ServiceManager.addService("package", m);
return m;
}
我們回到ActivityStarter的startActivityMayWait方法,繼續(xù)走會(huì)發(fā)現(xiàn)調(diào)用了startActivityLocked方法:
//繼續(xù)調(diào)用startActivityLocked方法:
int res = startActivityLocked(...省略一些參數(shù));
這是ActivityStarter的startActivityLocked方法:
final int startActivityLocked(...省略一些參數(shù)) {
//初始化了一個(gè)錯(cuò)誤標(biāo)志,常見的錯(cuò)誤有很多,比如:找不到Activity,Activity沒有在清單文件中注冊(cè)等等
int err = ActivityManager.START_SUCCESS;
//獲取調(diào)用者的一些信息
ProcessRecord callerApp = null;
if (caller != null) {
callerApp = mService.getRecordForAppLocked(caller);
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
} else {
err = ActivityManager.START_PERMISSION_DENIED;
}
}
//省略一些代碼
if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
//錯(cuò)誤:找不到Activity的意圖
err = ActivityManager.START_INTENT_NOT_RESOLVED;
}
if (err == ActivityManager.START_SUCCESS && aInfo == null) {
//錯(cuò)誤:找不到Activity的Class類,比如說清單文件里面的類名寫錯(cuò)了
err = ActivityManager.START_CLASS_NOT_FOUND;
}
//省略一些代碼
//省略驗(yàn)證權(quán)限相關(guān)的代碼,因?yàn)橐粋€(gè)Activity的啟動(dòng)可能需要一些權(quán)限,尤其是自定義權(quán)限的時(shí)候
if (Build.PERMISSIONS_REVIEW_REQUIRED && aInfo != null) {
if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
aInfo.packageName, userId)) {
}
}
//如果沒有錯(cuò)誤信息的話,就會(huì)創(chuàng)建一個(gè)ActivityRecord,記錄著Activity的各種信息,例如返回結(jié)果的時(shí)候需要跳到哪個(gè)Activity的信息,Activity所在的進(jìn)程(例如啟動(dòng)一個(gè)沒有進(jìn)程的Activity的時(shí)候,如果發(fā)現(xiàn)ActivityRecord里面的進(jìn)程沒有被啟動(dòng)的時(shí)候,就需要去孵化一個(gè)進(jìn)程,這里在后面會(huì)有所分析)
ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
requestCode, componentSpecified, voiceSession != null, mSupervisor, container,
options, sourceRecord);
//省略一些代碼
try {
mService.mWindowManager.deferSurfaceLayout();
//調(diào)用startActivityUnchecked,無需檢查,真正去啟動(dòng)
err = startActivityUnchecked(...省略一些參數(shù));
} finally {
mService.mWindowManager.continueSurfaceLayout();
}
postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack);
return err;
}
調(diào)用startActivityUnchecked,無需檢查其他東西去啟動(dòng)Activity:
這個(gè)方法處理了Activity的啟動(dòng)模式,比如是否需要新建一個(gè)任務(wù)棧,棧里面是否需要復(fù)用已經(jīng)存在的Activity實(shí)例等等。而且啟動(dòng)模式還要配合flag,比如說NEW_TASK等。
并且在清單文件里面的啟動(dòng)模式的配置要優(yōu)先于flags。
private int startActivityUnchecked(...省略一些參數(shù)) {
//省略一些代碼
if (mReusedActivity != null) {
if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) != 0
|| mLaunchSingleInstance || mLaunchSingleTask) {
//查詢頂端的Activity
final ActivityRecord top = mReusedActivity.task.performClearTaskForReuseLocked(
mStartActivity, mLaunchFlags);
if (top != null) {
if (top.frontOfTask) {
top.task.setIntent(mStartActivity);
}
ActivityStack.logStartActivity(AM_NEW_INTENT, mStartActivity, top.task);
top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
mStartActivity.launchedFromPackage);
}
}
//省略一些代碼
}
if (mStartActivity.packageName == null) {
if (mStartActivity.resultTo != null && mStartActivity.resultTo.task.stack != null) {
mStartActivity.resultTo.task.stack.sendActivityResultLocked(
-1, mStartActivity.resultTo, mStartActivity.resultWho,
mStartActivity.requestCode, RESULT_CANCELED, null);
}
ActivityOptions.abort(mOptions);
return START_CLASS_NOT_FOUND;
}
//省略一些代碼
//調(diào)用目標(biāo)的Activity棧的startActivityLocked方法
mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
//省略一些代碼
}
Activity任務(wù)棧(Task)
任務(wù)棧里面存放著ActivityRecord,是一種后進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)。
比如Launcher去啟動(dòng)Activity的時(shí)候,就需要新建一個(gè)任務(wù)棧。調(diào)用系統(tǒng)的應(yīng)用的時(shí)候,比如相機(jī),如果不指定NEW_TASK,就會(huì)在自己的APP的任務(wù)棧里面啟動(dòng)。
比較特殊的就是單例模式,就是會(huì)新建一個(gè)任務(wù)棧。
棧也有順序的,我們看到的是正在顯示的棧,退出這個(gè)棧以后,就會(huì)顯示下一個(gè)棧。
在上面的方法的最后會(huì)調(diào)用目標(biāo)的Activity棧的startActivityLocked方法:
//調(diào)用目標(biāo)的Activity棧的startActivityLocked方法
mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
- ActivityStackSupervisor:APP的棧的管理類(管理的時(shí)候也是用棧的模型),比如哪個(gè)任務(wù)棧需要顯示,Activity需要選擇哪個(gè)棧去進(jìn)棧,并且檢查Intent的flags。
- ActivityStack:就是一個(gè)個(gè)被ActivityStackSupervisor管理的棧,管理者Activity。
下面我們分析ActivityStack的startActivityLocked:
final void startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition,
ActivityOptions options) {
//找到需要啟動(dòng)的Activity的任務(wù)棧,因?yàn)槊恳粋€(gè)Activity一定會(huì)分配一個(gè)任務(wù)棧
TaskRecord rTask = r.task;
//那大任務(wù)棧的ID
final int taskId = rTask.taskId;
// mLaunchTaskBehind tasks get placed at the back of the task stack.
if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
//如果不是后置任務(wù)(某些Activity進(jìn)棧之后還要處理一些操作),那就把這個(gè)任務(wù)棧加到最頂端,也就是成為有焦點(diǎn)的棧
//告訴WindowManager,把Task移到頂部,因?yàn)榇翱诘娘@示是由WindowManager來控制的。并且顯示這個(gè)任務(wù)棧里面最頂部的Activity。
insertTaskAtTop(rTask, r);
mWindowManager.moveTaskToTop(taskId);
}
TaskRecord task = null;
if (!newTask) {
//如果不需要啟動(dòng)一個(gè)新的任務(wù)棧的話,直接重復(fù)利用當(dāng)前的Task
boolean startIt = true;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
task = mTaskHistory.get(taskNdx);
if (task.getTopActivity() == null) {
// All activities in task are finishing.
continue;
}
if (task == r.task) {
if (!startIt) {
//如果不需要啟動(dòng)一個(gè)新的任務(wù)棧,直接把Activity添加到當(dāng)前最頂部的TASK,并且放到頂部
task.addActivityToTop(r);
//添加到回退棧
r.putInHistory();
//省略一些代碼
} else if (task.numFullscreen > 0) {
startIt = false;
}
}
}
//需要新建一個(gè)任務(wù)棧的話,就新建一個(gè),然后添加Activity,通知WM,具體代碼就不看了。
if (task == r.task && mTaskHistory.indexOf(task) != (mTaskHistory.size() - 1)) {
mStackSupervisor.mUserLeaving = false;
}
task = r.task;
task.addActivityToTop(r);
task.setFrontOfTask();
//...省略一些代碼
if (doResume) {
mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
}
}
接著調(diào)用ActivityStackSupervisor的resumeTopActivitiesLocked,下面繼續(xù)分析:
boolean resumeTopActivitiesLocked() {
return resumeTopActivitiesLocked(null, null, null);
}
根據(jù)調(diào)用關(guān)系鏈,會(huì)調(diào)用下面這個(gè)方法:
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
//省略一些代碼
if (isFrontStack(targetStack)) {
//調(diào)用ActivityStack的resumeTopActivityLocked方法查找需要暫停的Activity
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}
//省略一些代碼
}
ActivityStack的resumeTopActivityLocked如下:
final boolean resumeTopActivityLocked(ActivityRecord prev) {
return resumeTopActivityLocked(prev, null);
}
final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
//省略一些代碼
try {
result = resumeTopActivityInnerLocked(prev, options);
} finally {
inResumeTopActivity = false;
}
return result;
}
然后調(diào)用resumeTopActivityInnerLocked:
final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
//省略一些代碼
//找到第一個(gè)沒有被銷毀的Activity,根據(jù)ActivityStackSupervisor的成員變量所保存的數(shù)組來查找
//所找到的Activity將來準(zhǔn)備要進(jìn)入暫停狀態(tài)
//我們的APP所有Activity任務(wù)棧統(tǒng)一通過進(jìn)程通信交給ActivityStackSupervisor管理所有任務(wù)棧。
//因?yàn)锳ctivityStackSupervisor知道整個(gè)系統(tǒng)的哪個(gè)進(jìn)程死了,需要顯示哪個(gè)任務(wù)棧
ActivityRecord next = topRunningActivityLocked(null);
//省略一些代碼
//需要把當(dāng)前準(zhǔn)備暫停的Activity,從一些狀態(tài)數(shù)組里面移除
mStackSupervisor.mStoppingActivities.remove(next);
mStackSupervisor.mGoingToSleepActivities.remove(next);
next.sleeping = false;
mStackSupervisor.mWaitingVisibleActivities.remove(next);
//調(diào)用startPausingLocked暫停最頂部的Activity,通過這樣做的話,它將來就能夠復(fù)活resume
boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
if (mResumedActivity != null) {
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
}
//省略一些代碼
ActivityStack lastStack = mStackSupervisor.getLastStack();
//一個(gè)Activity要啟動(dòng)的話,需要先判斷app以及thread還存不存在,如不存在就需要重新創(chuàng)建一個(gè)進(jìn)程。
//比如說從launcher啟動(dòng)Activity
if (next.app != null && next.app.thread != null) {
//無需創(chuàng)建進(jìn)程
} else {
//需要啟動(dòng)的的Activity還沒有啟動(dòng)對(duì)應(yīng)的進(jìn)程,需要去啟動(dòng)進(jìn)程
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
} else {
//省略一些代碼
//重新啟動(dòng)進(jìn)程
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
return true;
}
startPausingLocked:
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
boolean dontWait) {
//找到上一個(gè)需要暫停的Activity
ActivityRecord prev = mResumedActivity;
if (prev == null) {
if (!resuming) {
mStackSupervisor.resumeTopActivitiesLocked();
}
return false;
}
//先判斷之前的Activity是否存在,如果存在,需要進(jìn)行進(jìn)程間通信,通知那個(gè)app去停止Activity
//之所以每一個(gè)Activity都需要用一個(gè)ActivityRecord去記錄,就是因?yàn)樾枰涗浢恳粋€(gè)Activity所在進(jìn)程等等信息,方便系統(tǒng)去管理
if (prev.app != null && prev.app.thread != null) {
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
prev.userId, System.identityHashCode(prev),
prev.shortComponentName);
mService.updateUsageStats(prev, false);
//如果存在,需要進(jìn)行進(jìn)程間通信,通知那個(gè)app去停止Activity
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
userLeaving, prev.configChangeFlags, dontWait);
} catch (Exception e) {
mPausingActivity = null;
mLastPausedActivity = null;
mLastNoHistoryActivity = null;
}
}
//省略一些代碼
}
schedulePauseActivity方法會(huì)發(fā)起進(jìn)程間通信,通知即將要停止的Activity所在的進(jìn)程,去暫停這個(gè)Activity。最終會(huì)在那個(gè)進(jìn)程的ActivityThread里面回調(diào)schedulePauseActivity方法:
實(shí)質(zhì)上就是發(fā)送消息給Handler,然后調(diào)用,去停止Activity。
public final void schedulePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
int seq = getLifecycleSeq();
//省略一些代碼
sendMessage(
finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
token,
(userLeaving ? USER_LEAVING : 0) | (dontReport ? DONT_REPORT : 0),
configChanges,
seq);
}
Handler里面的case如下:
case PAUSE_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
SomeArgs args = (SomeArgs) msg.obj;
handlePauseActivity((IBinder) args.arg1, false,
(args.argi1 & USER_LEAVING) != 0, args.argi2,
(args.argi1 & DONT_REPORT) != 0, args.argi3);
maybeSnapshot();
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
handlePauseActivity:
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport, int seq) {
ActivityClientRecord r = mActivities.get(token);
if (!checkAndUpdateLifecycleSeq(seq, r, "pauseActivity")) {
return;
}
if (r != null) {
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
//真正去執(zhí)行暫停Activity
performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
// Tell the activity manager we have paused.也就是說,先停止,然后回饋給AMS的activityPaused方法
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
mSomeActivitiesChanged = true;
}
}
performPauseActivity:
final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState, String reason) {
ActivityClientRecord r = mActivities.get(token);
return r != null ? performPauseActivity(r, finished, saveState, reason) : null;
}
然后又會(huì)調(diào)用performPauseActivity:
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState) {
//省略一些代碼
try {
//省略一些代碼
//真正去停止Activity
mInstrumentation.callActivityOnPause(r.activity);
EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
r.activity.getComponentName().getClassName());
if (!r.activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onPause()");
}
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
}
}
然后:
public void callActivityOnPause(Activity activity) {
activity.performPause();
}
最后回調(diào)Activity的onPause方法
final void performPause() {
//省略一些代碼
onPause();
//省略一些代碼
}
在handlePauseActivity的最后還要:
// Tell the activity manager we have paused.也就是說,先停止,然后回饋給AMS的activityPaused方法
// 這就解釋了為什么新啟動(dòng)的Activity啟動(dòng)之前,舊的先onPause
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
@Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
synchronized(this) {
//AMS去啟動(dòng)棧頂部Activity
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
stack.activityPausedLocked(token, false);
}
}
Binder.restoreCallingIdentity(origId);
}
ActivityStackSupervisor、ActivityStack只是管理了Activity的棧,棧放什么,而真真正正去處理四大組件啟動(dòng)的還是AMS服務(wù)。之前的一系列操作只是進(jìn)行了一些棧的管理操作,然后通知APP進(jìn)程暫停,然后APP進(jìn)程再去通知AMS去啟動(dòng)棧頂部Activity。
//Activity已經(jīng)暫停了
final void activityPausedLocked(IBinder token, boolean timeout) {
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
//然后調(diào)用completePauseLocked,表示上一個(gè)Activity已經(jīng)停止完成了,然后resume要啟動(dòng)的Activity
completePauseLocked(true);
}
}
}
然后調(diào)用completePauseLocked,表示上一個(gè)Activity已經(jīng)停止完成了,然后resume要啟動(dòng)的Activity:
private void completePauseLocked(boolean resumeNext) {
ActivityRecord prev = mPausingActivity;
//省略一些代碼
if (resumeNext) {
//拿到頂部任務(wù)棧
final ActivityStack topStack = mStackSupervisor.getFocusedStack();
if (!mService.isSleepingOrShuttingDown()) {
mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
}
}
//省略一些代碼
}
然后調(diào)用:
boolean resumeTopActivitiesLocked() {
return resumeTopActivitiesLocked(null, null, null);
}
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
Bundle targetOptions) {
//省略一些代碼
if (isFrontStack(targetStack)) {
result = targetStack.resumeTopActivityLocked(target, targetOptions);
}
//省略一些代碼
}
又會(huì)回來調(diào)用ActivityStack的resumeTopActivityLocked,里面繼續(xù)調(diào)用resumeTopActivityInnerLocked:
if (next.app != null && next.app.thread != null) {
//不需要啟動(dòng)進(jìn)程
} else {
//需要啟動(dòng)進(jìn)程
if (!next.hasBeenLaunched) {
next.hasBeenLaunched = true;
}
//省略一些代碼
mStackSupervisor.startSpecificActivityLocked(next, true, true);
}
先判斷app的進(jìn)程有沒有啟動(dòng),例如連續(xù)啟動(dòng)。
void startSpecificActivityLocked(ActivityRecord r,
boolean andResume, boolean checkConfig) {
//省略一些代碼
if (app != null && app.thread != null) {
//不需要啟動(dòng)進(jìn)程
}
//啟動(dòng)進(jìn)程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
"activity", r.intent.getComponent(), false, false, true);
}
調(diào)用AMS的方法來啟動(dòng)進(jìn)程:
//看到hosting,證明Java準(zhǔn)備跟底層的C/C++通信了
final ProcessRecord startProcessLocked(String processName,
ApplicationInfo info, boolean knownToBeDead, int intentFlags,
String hostingType, ComponentName hostingName, boolean allowWhileBooting,
boolean isolated, boolean keepIfLarge) {
return startProcessLocked(...省略一些參數(shù));
}
final ProcessRecord startProcessLocked(...省略一些參數(shù)) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
//省略一些代碼
//創(chuàng)建app對(duì)象,但是這時(shí)候進(jìn)程還沒啟動(dòng)
//省略一些代碼
if (app == null) {
checkTime(startTime, "startProcess: creating new process record");
app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
}
//啟動(dòng)進(jìn)程
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
}
啟動(dòng)進(jìn)程:
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
long startTime = SystemClock.elapsedRealtime();
//省略一些代碼
try {
if (!app.isolated) {
//省略一些代碼
//獲取PID、UID
gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
}
checkTime(startTime, "startProcess: building args");
if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopComponent != null
//獲取包名
&& app.processName.equals(mTopComponent.getPackageName())) {
uid = 0;
}
}
int debugFlags = 0;
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
//開始配置Zygote進(jìn)程
debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
// Also turn on CheckJNI for debuggable apps. It's quite
// awkward to turn on otherwise.
debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
}
//省略一些代碼
//android.app.ActivityThread是Java層的入口類
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
//開始啟動(dòng)進(jìn)程
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
//開始拼裝啟動(dòng)的腳本,最后寫到C/C++里面
StringBuilder buf = mStringBuilder;
buf.setLength(0);
buf.append("Start proc ");
buf.append(startResult.pid);
buf.append(':');
buf.append(app.processName);
buf.append('/');
//省略一些腳本的拼裝
synchronized (mPidsSelfLocked) {
this.mPidsSelfLocked.put(startResult.pid, app);
if (isActivityProcess) {
//把這些信息拼裝成一個(gè)消息,然后通過Handler來處理,最后是跟底層通信,通過C/C++的方式去啟動(dòng)進(jìn)程
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, startResult.usingWrapper
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
} catch (RuntimeException e) {
}
}
最后ActivityThread會(huì)啟動(dòng),啟動(dòng)ActivityThread的main方法:
public static void main(String[] args) {
//省略一些代碼
Environment.initForCurrentUser();
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
//把當(dāng)前進(jìn)程attach到系統(tǒng)中
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
Looper.loop();
}
如下:
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
//調(diào)用IActivityManager,通過進(jìn)程間通信,綁定Application。IActivityManager的實(shí)現(xiàn)類是AMS
//查看AMS的實(shí)現(xiàn)之后,又會(huì)調(diào)用attachApplicationLocked,然后又會(huì)調(diào)用ActivityStackSupervisor的attachApplicationLocked
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
}
}
//省略一些代碼
}
AMS的attachApplicationLocked方法有一句核心代碼如下,然后又會(huì)調(diào)用ActivityStackSupervisor的attachApplicationLocked:
//如果進(jìn)程已經(jīng)啟動(dòng)了,而且在棧頂部有一個(gè)屬于這個(gè)進(jìn)程的Activity需要啟動(dòng)
if (normalMode) {
try {
if (mStackSupervisor.attachApplicationLocked(app)) {
didSomething = true;
}
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
進(jìn)程被創(chuàng)建,不一定需要Activity的啟動(dòng)。Activity跟進(jìn)程還沒有關(guān)聯(lián),因此realStartActivityLocked:
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
for (...省略) {
ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
for (...省略) {
ActivityRecord hr = stack.topRunningActivityLocked(null);
if (hr != null) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
//繼續(xù)調(diào)用realStartActivityLocked
if (realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (RemoteException e) {
}
}
}
}
}
}
realStartActivityLocked里面有這樣一句:
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,
results, newIntents, !andResume, mService.isNextTransitionForward(),
profilerInfo);
通過進(jìn)程間通信,回到APP的ActivityThread,發(fā)送消息給H,然后啟動(dòng):
case LAUNCH_ACTIVITY: {
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
} break;
然后:
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
//省略一些代碼
//先初始化窗口
WindowManagerGlobal.initialize();
//然后performLaunchActivity
Activity a = performLaunchActivity(r, customIntent);
//省略一些代碼
}
performLaunchActivity:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
ActivityInfo aInfo = r.activityInfo;
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
ComponentName component = r.intent.getComponent();
if (component == null) {
component = r.intent.resolveActivity(
mInitialApplication.getPackageManager());
r.intent.setComponent(component);
}
if (r.activityInfo.targetActivity != null) {
component = new ComponentName(r.activityInfo.packageName,
r.activityInfo.targetActivity);
}
Activity activity = null;
try {
//通過反射的方式去創(chuàng)建Activity
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
r.intent.prepareToEnterProcess();
if (r.state != null) {
r.state.setClassLoader(cl);
}
} catch (Exception e) {
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
//省略一些代碼
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
//設(shè)置主題
activity.setTheme(theme);
}
activity.mCalled = false;
//回調(diào)OnCreate
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException(
"Activity " + r.intent.getComponent().toShortString() +
" did not call through to super.onCreate()");
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
//回調(diào)onStart、onResum等
activity.performStart();
r.stopped = false;
}
}
} catch (SuperNotCalledException e) {
} catch (Exception e) {
}
return activity;
}
關(guān)于newActivity:
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return (Activity)cl.loadClass(className).newInstance();
}
幾個(gè)有關(guān)的核心類
- ActivityManagerService(本地Stub是ActivityManagerNative):系統(tǒng)進(jìn)程里面的一個(gè)服務(wù),管理四大組件的生命周期等等。
- ActivityThread:Android應(yīng)用程序的Java層入口函數(shù)。
- PackageManagerService:清單的掃描、注冊(cè)。
- ActivityStackSupervisor:管理所有任務(wù)棧,是通過棧的模型去管理的,是否需要新建任務(wù)棧?等等。
- ActivityStack:任務(wù)棧,管理任務(wù)棧里面的Activity。
- WindowManager:只管理當(dāng)前最頂部的棧的Activity的UI的渲染。
Activity的啟動(dòng)總結(jié)如下:

這里先對(duì)這個(gè)圖進(jìn)行一些必要的說明:
- 這是MyActivity的啟動(dòng)流程,流程是從左邊開始,逆時(shí)針旋轉(zhuǎn)。主要展示了Application怎么調(diào)到Android System Service,Android System Service如何反過來調(diào)Application。
- Instrumentation是Activity的一個(gè)成員,這里用聚合表示。Instrumentation用于記錄Activity的一切操作。
- Application以及H都是ActivityThread的內(nèi)部類
- ActivityManagerService,簡(jiǎn)稱AMS,是Android系統(tǒng)服務(wù)中的一個(gè)核心模塊,其他的還有WindowsManagerService(WMS)、PackageManagerService(PMS)、NotificationManagerService(NMS)等等。AMS主要的功能是管理應(yīng)用進(jìn)程以及應(yīng)用進(jìn)程中的組件、內(nèi)存管理。
- 從上面的圖可以看出Android系統(tǒng)的幾個(gè)明顯的層次關(guān)系。
思想
- 大量采用了C/S架構(gòu),交給遠(yuǎn)程進(jìn)程統(tǒng)一管理,這樣才能夠?qū)崿F(xiàn)多進(jìn)程,多窗口,有條不紊。
- 模塊化的思想,不同的模塊管理不同的東西。多建立package,分模塊,比如說網(wǎng)絡(luò)訪問專門一個(gè)包。
- 分層次思想,不能一個(gè)類所有事情都管理了。
如果覺得我的文字對(duì)你有所幫助的話,歡迎關(guān)注我的公眾號(hào):
我的群歡迎大家進(jìn)來探討各種技術(shù)與非技術(shù)的話題,有興趣的朋友們加我私人微信huannan88,我拉你進(jìn)群交(♂)流(♀)。