一些可以了解的知識
和啟動流程相關的類
從這篇文章拿來的圖片
(https://blog.csdn.net/zplxl99/article/details/104507480/)
-
ActivityTaskManagerService
: 是Android 10新增加的系統(tǒng)服務類劳澄,可以看做幫AMS分攤工作的類 -
ActivityStackSupervisor
: 負責所有Activity棧的管理 -
ActivityStack
: 內部維護一個 TaskRecord隊列 用來保存TaskRecord -
TaskRecord
: 內部維護一個 ActivityRecord隊列 用來保存ActivityRecord -
ActivityRecord
: 代表一個activity充坑,保存了Activity的各種信息提供給AMS使用
Launcher啟動
- 你的手機桌面就是一個Launcher進程,當你點擊桌面App時舌仍。他就會通過Binder通信(跨進程通信)去請求system_server進程啟動一個Activity
- system_server進程是一個系統(tǒng)進程,里面基本存放了所有手機Service服務袱贮,其中管理我們App四大組件的AMS也在其中
- 如果你的APP沒啟動過概而,AMS會請求Zygote進程去fork出你的App進程悯仙,這就是冷啟動
-
如果你的APP啟動過了,已經(jīng)fork出來了想诅,那么就會直接啟動你的第一個Activity召庞,這就是熱啟動
image.png
Application啟動流程
ActivityThread.java
從App進程被創(chuàng)建出來后,就會執(zhí)行Main函數(shù)
通過貼出的關鍵代碼来破,我們可以這樣整理一下
- main函數(shù)創(chuàng)建出了一個ActivityThread實例篮灼,
- 通過ActivityManager獲取到AMS實例代理
- 調用AMS的方法attachApplication,請求創(chuàng)建綁定Application徘禁,并把ApplicationThread給AMS
===== ActivityThread.java =====
public static void main(String[] args) {
....
// 創(chuàng)建出ActivityThread實例(注意這不是一個線程W缬铡!)
ActivityThread thread = new ActivityThread();
// 然后調用attach去做一些綁定
thread.attach(false, startSeq);
....
}
==== 還是在ActivityThread.java ====
private void attach(boolean system, long startSeq) {
// 注意這個變量送朱,就是把當前ActivityThread實例保存在當前類的sCurrentActivityThread變量中
sCurrentActivityThread = this;
// 上面?zhèn)魅氲氖莝ystem = FALSE娘荡,進入
mSystemThread = system;
if (!system) {
...
// 拿到一個IActivityManager對象干旁,這里直接當做是AMS
final IActivityManager mgr = ActivityManager.getService();
try {
// 重點方法,mgr(= AMS),也就是調用AMS的方法
// 注意這里傳入的 mAppThread 變量
mgr.attachApplication(mAppThread, startSeq);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
// 添加GC內存回收的一個箭筒炮沐,感興趣可以了解一下
// Watch for getting close to heap limit.
BinderInternal.addGcWatcher(new Runnable(){});
} else {
....
}
...
}
==== 還是在ActivityThread.java ====
通過搜索發(fā)現(xiàn)争群,mAppThread就是一個ApplicationThread實例,這個實例是ActivityThread的一個內部類
@UnsupportedAppUsage
final ApplicationThread mAppThread = new ApplicationThread();
ActivityManagerService.java
- 給Binder通信賦pid,uid保證安全性
- 回到ActivityThread的ApplicationThread大年,調用bindApplication
==== ActivityManagerService.java ====
public final void attachApplication(IApplicationThread thread, long startSeq) {
if (thread == null) {
throw new SecurityException("Invalid application interface");
}
synchronized (this) {
// 這里每一句話都很重要
// 但是根據(jù)流程我們會進入到4方法中去
// Bindder通信安全换薄,自帶驗證信息就是在這里賦值的(1,2,4,5)也是Bindder安全的原因
1.int callingPid = Binder.getCallingPid();
2.final int callingUid = Binder.getCallingUid();
3.final long origId = Binder.clearCallingIdentity();
4.attachApplicationLocked(thread, callingPid, callingUid, startSeq);
5.Binder.restoreCallingIdentity(origId);
}
}
==== 還是 ActivityManagerService.java ====
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
int pid, int callingUid, long startSeq) {
....
// 這里的thread就是 mAppThread=ApplicationThread()
// 所以調用了這個函數(shù)翔试,流程又會回到ActivityThread.java文件去
thread.bindApplication(各種參數(shù))
....
// 記住bindApplication執(zhí)行完畢后轻要,流程又會回到這邊來,這里先貼出代碼垦缅,混個眼熟冲泥,
if (normalMode) {
try {
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
}
ActivityThread.java
- bindApplication會發(fā)送一個Handler消息
- 而處理這個消息的Handler也在ActivityThread中的Class H
- H收到消息后就會開始執(zhí)行創(chuàng)建并綁定Application的操作
- 并且在創(chuàng)建完Application后,還會初始化ContentProvide
=== 在ActivityThread.java中的內部類ApplicationThread中 ===
public final void bindApplication(String processName, ApplicationInfo appInfo,......){
....(給data設置各種參數(shù)值)
// 發(fā)送一個Handler消息
sendMessage(H.BIND_APPLICATION, data);
}
=== 在ActivityThread.java中的內部類H中 ===
class H extends Handler {
public static final int BIND_APPLICATION = 110;
public void handleMessage(Message msg) {
if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
// 發(fā)送了消息之后在這里接收失都,然后綁定Application
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
}
}
=== 在ActivityThread.java中 ===
// 說實話這里比較抽象柏蘑,如果不查找資料的話,進去容易找不到粹庞,不知道看哪里然后出不來
private void handleBindApplication(AppBindData data) {
// 創(chuàng)建Application
app = data.info.makeApplication(data.restrictedBackupMode, null);
// 賦值給本地變量
mInitialApplication = app;
// ContentProviders 初始化
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
installContentProviders(app, data.providers);
}
}
try {
// 調用Application的onCreate方法
// (方法點進去是有注釋表明這是調用Application的onCreate)
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
// 這里也可以看到咳焚,拋出的錯誤信息是無法創(chuàng)建Applicaiton
throw new RuntimeException(
"Unable to create application " + app.getClass().getName()
+ ": " + e.toString(), e);
}
}
}
==== 這里進入makeApplication()方法看一下 ====
public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {
// 創(chuàng)建context
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
// 創(chuàng)建Application,并把上下文傳入
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
return app;
}
==== 這里進入newApplication()方法看一下 ====
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = getFactory(context.getPackageName())
.instantiateApplication(cl, className);
// 這里最終會調用到attachBaseContext庞溜,所以這個方法在onCreate方法之前革半,并且還能拿到Context
app.attach(context); --> attachBaseContext(context);
return app;
}
Activity啟動流程
Application結束后,我們會回到ActivityManagerService.java流码,回到那個混臉熟的代碼塊那邊去
ActivityManagerService.java
- 這里就是對Activity又官,Service,BroadCast的啟動
- Activity的啟動會放在LocalService中去
==== ActivityManagerService.java ====
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,....){
// See if the top visible activity is waiting to run in this process...
if (normalMode) {
try {
// 這里雖然調用的方法是attachApplication漫试,但是他確實是Activity相關的
// mAtmInternal 是 ActivityTaskManagerService中的內部類LocalService
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
} catch (Exception e) {
Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
badApp = true;
}
}
// 這是Service
// Find any services that should be running in this process...
if (!badApp) {
didSomething |= mServices.attachApplicationLocked(app, processName);
}
// 這是Broadcast
// Check if a next-broadcast receiver is in this process...
if (!badApp && isPendingBroadcastProcessLocked(pid)) {
didSomething |= sendPendingBroadcastsLocked(app);
}
}
ActivityTaskManagerService.java
這里是我感覺整個流程最抽象的地方了六敬,感覺需要配合WMS一起理解比較好
- 這就是一系列調用流程,但是防止找不到就記錄下驾荣,反正最終會流入ActivityStackSupervisor.java
==== LocalService.java ====
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
synchronized (mGlobalLockWithoutBoost) {
if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
}
try {
// 這里會走整個方法
// 這里沒什么說法外构,就是沒什么地方能進去,就走這個方法
return mRootWindowContainer.attachApplication(wpc);
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
}
RootWindowContainer.java
==== RootWindowContainer.java ====
boolean attachApplication(WindowProcessController app) throws RemoteException {
final PooledFunction c = PooledLambda.obtainFunction(
// 這里繼續(xù)進入 startActivityForAttachedApplicationIfNeeded
// 這里也沒什么說法播掷,就是看名字像就點進去看了
RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());
}
==== 還是RootWindowContainer.java ====
private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
WindowProcessController app, ActivityRecord top) {
if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null
|| app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
return false;
}
try {
// 這里繼續(xù)進入审编,會走到ActivityStackSupervisor.java
if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
true /*checkConfig*/)) {
mTmpBoolean = true;
}
} catch (RemoteException e) {
Slog.w(TAG, "Exception in new application when starting activity "
+ top.intent.getComponent().flattenToShortString(), e);
mTmpRemoteException = e;
return true;
}
return false;
}
ActivityStackSupervisor.java
- 這里個人感覺這幾個點比較重要
- clientTransaction,牢記這個玩意歧匈,因為他會一直一直一直傳遞下去
- clientTransaction.addCallback(LaunchActivityItem) 簡單理解 用一個List存放LaunchActivityItem
- clientTransaction.setLifecycleStateRequest(lifecycleItem) 簡單理解 存放下一個Activity要到的狀態(tài)
- 最終走到ActivityThread的父類 ClientTransactionHandler 發(fā)送Handler消息
==== ActivityStackSupervisor.java ====
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
boolean andResume, boolean checkConfig) throws RemoteException {
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(
proc.getThread(), r.appToken);
// 創(chuàng)建初始的LaunchActivityItem垒酬,并把intent傳入,我們打開Activity使用的Intent也是這個
// addCallback 就是添加當一個List中去,記住是把LaunchActivityItem添加到List中
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),....)
// 創(chuàng)建一個與Activity生命周期相關的Item
if (andResume) {
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
lifecycleItem = PauseActivityItem.obtain();
}
// 設置生命周期過程中勘究,下一步需要到達的哪個生命周期
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// mService 是 ActivityTaskManagerService
// getLifecycleManager() 是 ClientLifecycleManager
// 記得這個clientTransaction進行了傳遞矮湘,他是有Activity信息的
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
}
ClientLifecycleManager.java
===== ClientLifecycleManager.java ====
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
final IApplicationThread client = transaction.getClient();
// 這里又走到ClientTransaction.java中去
transaction.schedule();
...
}
ClientTransaction.java
private IApplicationThread mClient;
public void schedule() throws RemoteException {
// mClient == IApplicationThread
// IApplicationThread == ApplicationThread == ActivityThread.java
// 這個this就是上面的clientTransaction
mClient.scheduleTransaction(this);
}
ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
// 又調用ActivityThread的scheduleTransaction
// 但是在ActivityThread中找不到這個方法
// 找不到就看看父類
// transaction == clientTransaction 繼續(xù)傳遞
ActivityThread.this.scheduleTransaction(transaction);
}
}
ClientTransactionHandler.java
public abstract class ClientTransactionHandler {
void scheduleTransaction(ClientTransaction transaction) {
transaction.preExecute(this);
// 這里發(fā)送消息,有回到ActivityThread的Class H 中去了
// clientTransaction最終是放到了msg.obj中
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
}
ActivityThread.java
// 這就看做是執(zhí)行各種生命周期Item的執(zhí)行器(我是這么理解的)
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
public void handleMessage(Message msg) {
case EXECUTE_TRANSACTION:
// 這里從msg中取出clientTransaction
final ClientTransaction transaction = (ClientTransaction) msg.obj;
// 接著execute執(zhí)行這個clientTransaction
mTransactionExecutor.execute(transaction);
if (isSystem()) {
// Client transactions inside system process are recycled on the client side
// instead of ClientLifecycleManager to avoid being cleared before this
// message is handled.
transaction.recycle();
}
// TODO(lifecycler): Recycle locally scheduled transactions.
break;
}
TransactionExecutor.java
==== TransactionExecutor.java ====
public void execute(ClientTransaction transaction) {
// transaction是啥?乱顾,是一直傳遞過來的clientTransaction
...
// 循環(huán)遍歷回調請求的所有狀態(tài)并在適當?shù)臅r間執(zhí)行它們
executeCallbacks(transaction);
// 轉換到最終狀態(tài)
executeLifecycleState(transaction);
mPendingActions.clear();
if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
==== 還是TransactionExecutor.java ====
public void executeCallbacks(ClientTransaction transaction) {
// transaction是啥?板祝,是一直傳遞過來的clientTransaction
// getCallbacks是啥?走净,把addCallback對應方法券时,就是拿出存放了LaunchActivityItem的List
final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
final int size = callbacks.size();
// 然后遍歷這個List
for (int i = 0; i < size; ++i) {
// 那么我們取出的第一個item,不就是LauncherActivityItem了嗎
final ClientTransactionItem item = callbacks.get(i);
if (closestPreExecutionState != UNDEFINED) {
cycleToPath(r, closestPreExecutionState, transaction);
}
// 接著執(zhí)行LaunchActivityItem的方法
item.execute(mTransactionHandler, token, mPendingActions);
item.postExecute(mTransactionHandler, token, mPendingActions);
}
}
==== 還是TransactionExecutor.java ====
// executeCallbacks 執(zhí)行完畢后就執(zhí)行 executeLifecycleState伏伯,這個方法比較簡單橘洞,就先說了
private void executeLifecycleState(ClientTransaction transaction) {
// 獲取開始設置的 需要到達的 狀態(tài)
// 從流程來看,現(xiàn)在這個就是 ResumeActivityItem
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
...
// 接著就是ResumeActivityItem说搅,最終也就是 Activity.performResume()
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
LaunchActivityItem.java
==== LaunchActivityItem.java ====
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions) {
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
// Activity信息
ActivityClientRecord r = new ActivityClientRecord(...);
// client == ClientTransactionHandler == ActivityThread.java
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
ActivityThead.java
public Activity handleLaunchActivity(ActivityClientRecord r,...,Intent customIntent){
// 這里返回拿到一個Activity炸枣,說明里面創(chuàng)建了Activity
final Activity a = performLaunchActivity(r, customIntent);
}
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// 創(chuàng)建context
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
// 類加載器
java.lang.ClassLoader cl = appContext.getClassLoader();
// 反射生成Activity
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) {
// 報錯信息也能看出,這是在創(chuàng)建Activity
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
}
}
....
// 綁定各種信息弄唧,可以自己進去看一看
activity.attach(....)
// 這里我也不知道走哪里适肠,但是不管哪個都是執(zhí)行 activity.performCreate()生命周期流程開始了
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
// 設置成ON_CREATE
r.setState(ON_CREATE);
}
然后Activity就這樣啟動了并走到了OnResume方法去了
總結一下
面試問到,說一下點擊Launcher的后候引,App啟動流程
- Launcher進程請求AMS侯养,AMS請求Zygote進程,都是通過Binder通信的澄干,fork出我們的App
- ActivityThread的main函數(shù)為入口逛揩,通過AMS實例的代理,幫助我們綁定Applicaiton(細節(jié)可自己補充)
- 綁定完Applicaiton麸俘,對Activity對應的生命周期生成對應的item類辩稽,然后交給一個執(zhí)行器去執(zhí)行,每執(zhí)行一個item都會調用activity的方法从媚,然后又會推進到下一個生命周期的狀態(tài)
最后
這只是簡單的走一下流程逞泄,畢竟FrameWork層的東西,看多幾遍感覺還是懵的拜效,但是多看幾遍還是會有收獲的
而且里面還有很多細節(jié)炭懊,一些變量,包括和其他系統(tǒng)Service相關的東西拂檩,都是需要去想一想的,感覺也挺有意思的嘲碧。