前言
曾經(jīng)我也有迷茫過,android開發(fā)過一定經(jīng)驗(yàn)届囚,我還要干嘛?學(xué)其他語言是尖?經(jīng)過幾經(jīng)思想斗爭意系,我選擇了專攻android之路,在我android未達(dá)到高層級(jí)別饺汹,我不會(huì)花太多精力去學(xué)其他蛔添,畢竟android是我飯碗,連飯碗都丟了兜辞,還能指望你能學(xué)好其他的迎瞧?那么問題來了怎么專攻?對android底層的了解逸吵,無疑對你上層代碼使用能更加的 輕車熟路凶硅、避免bug。所有才有了源碼分析系列的博客
“好記性不如爛筆頭”扫皱,在看過很多android的FrameWork源碼足绅,過幾天再回想一下,總是零零散散韩脑,不成知識(shí)體系氢妈,自己動(dòng)手一步一記錄源碼分析的過程。同時(shí)也給一些想進(jìn)一步了解android開發(fā)一個(gè)方向扰才。讓我們共同努力。
怎么做
1厕怜、工具:android studio
2衩匣、雙擊Shift查找api文件
3、由外到內(nèi)的分析粥航,一層一層的解刨
activity啟動(dòng)分析
//kotlin 語言
val intent = Intent(this@MainActivity, Main2Activity::class.java)
this.startActivity(intent)
相信大家對這段代碼用得輕車熟路了琅捏,我們用它啟動(dòng)一個(gè)activity。Ctrl+鼠標(biāo)左擊startActivity递雀。往里面接著看
@Override
public void startActivity(Intent intent) {
this.startActivity(intent, null);
}
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -1, options);
} else {
startActivityForResult(intent, -1);
}
}
跳轉(zhuǎn)到了Activity.java的startActivity(Intent intent)柄延,細(xì)看的有兩個(gè)重載函數(shù),核心代碼在帶有兩個(gè)參數(shù)的函數(shù)中的startActivityFoResult(Intent intent, int requestCode, @Nullable Bundle options)
- intent:包含啟動(dòng)activity的信息。
- requestCode:請求標(biāo)識(shí)字段(略過)
- options:存儲(chǔ)一些啟動(dòng)activity的參數(shù)搜吧,比如切換動(dòng)畫市俊,一些附帶數(shù)據(jù)等等,詳細(xì)的可以看ActivityOptions類滤奈。常用的我們默認(rèn)為null摆昧。
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
@Nullable Bundle options) {
if (mParent == null) {//mParent=Activity (1)
options = transferSpringboardActivityOptions(options);
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, this,
intent, requestCode, options);
if (ar != null) {
mMainThread.sendActivityResult(
mToken, mEmbeddedID, requestCode, ar.getResultCode(),
ar.getResultData());
}
if (requestCode >= 0) {
mStartedActivity = true;
}
cancelInputsAndStartExitTransition(options);
} else {//activity不為null (2)
if (options != null) {
mParent.startActivityFromChild(this, intent, requestCode, options);
} else {
mParent.startActivityFromChild(this, intent, requestCode);
}
}
}
我們先從(2)處開始分析,默認(rèn)activity不為null蜒程。最后都調(diào)用startActivityFromChild()绅你。
public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
int requestCode, @Nullable Bundle options) {
//對options進(jìn)行封裝,options為null就采用系統(tǒng)默認(rèn)
options = transferSpringboardActivityOptions(options);
//生成ActivityResult對象昭躺,里面包含resultCode和resultData
Instrumentation.ActivityResult ar =
mInstrumentation.execStartActivity(
this, mMainThread.getApplicationThread(), mToken, child,
intent, requestCode, options);
//執(zhí)行發(fā)送消息ActivityResult
if (ar != null) {
mMainThread.sendActivityResult(
mToken, child.mEmbeddedID, requestCode,
ar.getResultCode(), ar.getResultData());
}
//取消輸入功能和動(dòng)畫的執(zhí)行
cancelInputsAndStartExitTransition(options);
}
接下來忌锯,我們看下如何生成ActivityResult對象。方法Instrumentation.execStartActivity()
public ActivityResult execStartActivity(
Context who, IBinder contextThread, IBinder token, Activity target,
Intent intent, int requestCode, Bundle options) {
IApplicationThread whoThread = (IApplicationThread) contextThread;
Uri referrer = target != null ? target.onProvideReferrer() : null;
if (referrer != null) {
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
}
if (mActivityMonitors != null) {
synchronized (mSync) {
//遍歷ActivityMonitor,看是否存在這個(gè)Activity
final int N = mActivityMonitors.size();
for (int i=0; i<N; i++) {
final ActivityMonitor am = mActivityMonitors.get(i);
if (am.match(who, null, intent)) {
am.mHits++;
//如果當(dāng)該monitor阻塞activity啟動(dòng),也就是目標(biāo)Activity無法打開就直接return
if (am.isBlocking()) {
return requestCode >= 0 ? am.getResult() : null;
}
//如果存在就跳出循環(huán)
break;
}
}
}
}
try {
intent.migrateExtraStreamToClipData();
intent.prepareToLeaveProcess(who);
//真正的startActivity的方法领炫,其實(shí)核心功能在whoThread的scheduleLaunchActivity完成的
int result = ActivityManager.getService()
.startActivity(whoThread, who.getBasePackageName(), intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
token, target != null ? target.mEmbeddedID : null,
requestCode, 0, null, options);
//用于檢查打開Activity異常的方法偶垮,比如常見的Activity沒在AndroidManifest的話,
// 會(huì)拋出“...have you declared this activity in your AndroidManifest.xml?”異常
checkStartActivityResult(result, intent);
} catch (RemoteException e) {
throw new RuntimeException("Failure from system", e);
}
return null;
ActivityManager.getService().startActivity()方法才是啟動(dòng)activity的核心驹吮,內(nèi)部代碼會(huì)通過清單文件緩存池中獲取對應(yīng)activity针史,然后返回result標(biāo)記,如果沒有就會(huì)拋出have you declared this activity in your AndroidManifest.xml?”異常 碟狞。如果大家有了解過插件化開發(fā)原理啄枕,滴滴的VirtualApk方法就是從這里入手。通過ActivityManagerProxy 動(dòng)態(tài)代理類族沃,使得將插件化的清單文件緩存進(jìn)去频祝。首先進(jìn)去ActivityManager里面看一下getService方法
/**
* @hide
*/
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am; //ActivityManagerService
}
這里可能有人找不到對應(yīng)的startActivity方法在哪里,我這里是有安卓源碼通過搜索得到ActivityManagerService中有startActivity并且有addService()
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
到這里根本的startActivity方法終于找到了脆淹,讓我們直達(dá)內(nèi)部方法常空,一看究竟。ActivityManagerService.startActivity方法
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
enforceNotIsolatedCaller("startActivity");
userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
userId, false, ALLOW_FULL_ONLY, "startActivity", null);
//這里啟動(dòng)ActivityStarter類中的startActivityMayWait()
return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
profilerInfo, null, null, bOptions, false, userId, null, null,
"startActivityAsUser");
}
startActivityMayWait是個(gè)非常長的方法盖溺,里面處理的邏輯我們現(xiàn)在可以暫時(shí)不看漓糙,如何需要查看intent和flags的相關(guān)轉(zhuǎn)換時(shí)再仔細(xì)分析。
final int startActivityMayWait(IApplicationThread caller, int callingUid,
String callingPackage, Intent intent, String resolvedType,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, WaitResult outResult,
Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, int userId,
TaskRecord inTask, String reason) {
//省略
final ActivityRecord[] outRecord = new ActivityRecord[1];
int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor,
resultTo, resultWho, requestCode, callingPid,
callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
reason);
Binder.restoreCallingIdentity(origId);
//省略
}
int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask, String reason) {
//省略
mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
inTask);
//省略
return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
}
這里由于跳轉(zhuǎn)太多烘嘱,如果一步一步跟進(jìn)昆禽,最后會(huì)來到一個(gè)ApplicationThread中的scheduleLaunchActivity方法
@Override
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}
這里發(fā)送了一個(gè)Handle消息,如果對H.LAUNCH_ACTIVITY進(jìn)行查找蝇庭,會(huì)來到ActivityThread類中的一段代碼
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");//見名知意醉鳖,啟動(dòng)activity
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
//省略
Activity a = performLaunchActivity(r, customIntent);
//省略
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
//調(diào)用activity的onCreate()
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
//省略
return activity;
}
各個(gè)類的作用
以下僅供參考
Launcher:用戶看到的桌面,只是一個(gè)Activity
Instrumentation:在應(yīng)用代碼初始化之前運(yùn)行哮内,用于監(jiān)控應(yīng)用與系統(tǒng)的交互盗棵,管理著Application、Activity的生命周期
ActivityManagerService:處于安卓架構(gòu)的Framework層,運(yùn)行在SystemServer進(jìn)程中纹因,調(diào)度系統(tǒng)中的所有Activity喷屋,AMS會(huì)決定哪個(gè)Activity可以啟動(dòng)
ActivityStarted:決定了Activity是如何啟動(dòng)的,包含了intent和flags如何被轉(zhuǎn)換并且與任務(wù)棧相關(guān)聯(lián)的所有邏輯
ActivityStackSupervisor:Activity的棧管理類
ActivityStack:聲明和管理一個(gè)activity任務(wù)棧的狀態(tài)
ActivityThread:每一個(gè)應(yīng)用都有對應(yīng)的ActivityThread辐怕,進(jìn)程創(chuàng)建時(shí)會(huì)執(zhí)行ActivityThread的Main方法
ApplicationThread:主要負(fù)責(zé)與AMS交互
上一張流程圖逼蒙,加深印象