Android 11(platfrom 30)APP启动流程(含Activity)核心点记录
Posted 安卓开发-顺
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 11(platfrom 30)APP启动流程(含Activity)核心点记录相关的知识,希望对你有一定的参考价值。
前言:边分析,边记录 不断更新。
注意:阅读此文请同时打开android-30的源码,一步一步按文章同步跟进阅读源码,因为源码量太大,这里只能贴出部分核心代码。
场景一、从桌面点击APP图标进行启动
涉及到的核心进程:
step 1:
解析AndroidManifest文件 组装Intent对象
--> Activity --- startActivity
--> Activity --- startActivityForResult
--> Instrumentation --- execStartActivity
--- ActivityTaskManager.getService().startActivity 此处是通过ActivityTaskManager.getService()获取ActivityTaskManagerService (以下简称ATMS)的服务代理,跨进程调用ATMS的startActivity方法
--> ActivityTaskManagerService --- startActivity 1043行
--> ActivityTaskManagerService --- startActivityAsUser 1068行
--> ActivityTaskManagerService --- startActivityAsUser 1077行
--- getActivityStartController().obtainStarter 这里得到了一个 ActivityStarter对象
--> ActivityStarter --- execute 628行 669行
--> ActivityStarter --- executeRequest 835行 --- 1186行 startActivityUnchecked
--> ActivityStarter --- startActivityUnchecked 1512行 1521行
--> ActivityStarter --- startActivityInner 1587行 1731行
--> RootWindowContainer --- resumeFocusedStacksTopActivities 2285行
--> RootWindowContainer --- resumeFocusedStacksTopActivities 2289行 2299行
--> ActivityStack --- resumeTopActivityUncheckedLocked 1501行
--> ActivityStack --- resumeTopActivityInnerLocked 1532行 1961行
--> ActivityStackSupervisor --- startSpecificActivity 963行
这里是核心代码 是step 2 a 和 step 2 b的分支判断的地方
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig)
// Is this activity's application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread())
//step 2 b 当前APP进程已经存在 直接启动对应Activity
try
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
catch (RemoteException e)
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
final boolean isTop = andResume && r.isTopRunningActivity();
//step 2 a 当前APP进程不存在 调用 Zygote进程去fork APP进程
mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
我们先看step 2 a,这个分支最终还会走到step 2 b的位置(realStartActivityLocked),我们下面就来看下是如何走到这个方法的:
step 2 a:
--> ActivityStackSupervisor --- startSpecificActivity 986行 mService.startProcessAsyns
--> ActivityTaskManagerService --- startProcessAsync 5605行 5614
-->ActivityManagerInternal::startProcess 这里调到了AMS里面,AMS内部类LocalService继承了ActivityManagerInternal,对其方法了做了具体实现
--> ActivityManagerService$LocalService -- startProcess 19626
--> ActivityManagerService --startProcessLocked 3166
--> ProcessList --startProcessLocked 2325 2441
--> ProcessList --startProcessLocked 2317 2319
--> ProcessList --startProcessLocked 1728
--> ProcessList --startProcessLocked 1941行关键变量:entryPoint 程序入口
final String entryPoint = "android.app.ActivityThread";
此值最终会通过socket发给Zygote进程,然后zygote fork出进程后就调用android.app.ActivityThread 的main()方法。
我们继续往下看,一探究竟:
--> ProcessList --startProcessLocked 1943
--> ProcessList --startProcessLocked 1962 1997
--> ProcessList --startProcess 2201
--> ProcessList --startProcess 2284
//创建出AppZygote对象
final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
--> ProcessList --startProcess 2287
appZygote.getProcess().start(...进程各种信息)
appZygote.getProcess()得到的是ChildZygoteProcess
...
public class ChildZygoteProcess extends ZygoteProcess ...
start方法 是 ZygoteProcess 类里面的
--> ZygoteProcess --start 345
这里注释写的很明确了
If processes are enabled, a new process is created
and the static main() function of a processClass is executed there.
翻译:会在这个方法里创建出新的进程然后调用processClass的main()方法
processClass就是我们传进来的entryPoint参数即:android.app.ActivityThread
继续跟进:
--> ZygoteProcess --start 372
--> ZygoteProcess --startViaZygote 626 795
这里有个方法不要忽略了 openZygoteSocketIfNeeded() 通过socket连接zygote
--> ZygoteProcess --openZygoteSocketIfNeeded 1084 1086
--> ZygoteProcess --attemptConnectionToPrimaryZygote 1052 1055
--> ZygoteProcess -- connect 188
连接完成后,下面就是发送信息了:
--> ZygoteProcess --zygoteSendArgsAndGetResult 422 451
--> ZygoteProcess -- attemptUsapSendArgsAndGetResult 492
到此为止step 2 a 就结束了,接下来我们去zygote那边看看收到消息后是怎么处理消息,怎么调用ActivityThread的main()方法的。
step 3:
Zygote进程 接收SystemService进程的socket请求并处理:
我们就从Zygote进程的main()方法开始吧
--> ZygoteInit --- main() 832
--> ZygoteInit --- main() 917
//创建一个ZygoteServer类
zygoteServer = new ZygoteServer(isPrimaryZygote);
--> ZygoteInit --- main() 934
934行的代码这里注释中说明了:
// The select loop returns early in the child process after a fork and // loops forever in the zygote.
翻译:fork之后就会返回,并且这个runSelectLoop方法会在Zygote进程中一直循环下去,有请求就处理,处理完了接着循环等待新的socket请求。
934行在fork进程后就会返回,返回的是一个Runnable,然后947行执行这个Runnable
这里剧透下:我们从SystemService发过来的请求就是在runSelectLoop里面处理,处理后返回一个Runnable,这个Runnable里面就包含调用ActivityThread main()方法的逻辑,继续看:
--> ZygoteServer --- runSelectLoop 424
--> ZygoteServer --- runSelectLoop 545
//我们从SystemServer发过来的socket请求被封装成了一个ZygoteConnection
ZygoteConnection connection = peers.get(pollIndex);
//然后执行processOneCommand方法
final Runnable command = connection.processOneCommand(this);
--> ZygoteConnection --- processOneCommand 121
--> ZygoteConnection --- processOneCommand 257
pid = Zygote.forkAndSpecialize(...)
--> Zygote --- forkAndSpecialize 337
--> Zygote --- forkAndSpecialize 344
//调用native方法fork出进程 返回pid
int pid = nativeForkAndSpecialize()
调用native方法fork后我们回到ZygoteConnection 257的位置,继续往下看代码:
--> ZygoteConnection --- processOneCommand 273
--> ZygoteConnection --- processOneCommand 480 508
--> ZygoteInit --- childZygoteInit 1011 1014
--> RuntimeInit--- findStaticMain 345 通过反射找到main方法,封装成Runnable后返回
然后就回到:
--> ZygoteServer --- runSelectLoop 947 caller.run 执行此Runnable
说白了就是调用了 ActivityThread的main()方法!
到此为止step 3 就结束了,接下来看最精彩的 step 4,我们最熟悉的的启动流程就要来了!
step 4
--> ActivityThread--- main 7629 准备好主线程的Looper
Looper.prepareMainLooper();
--> ActivityThread--- main 7642 实例化一个ActivityThread对象 调用其attach方法
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq)
--> ActivityThread--- attach 7327 7334 得到AMS
这里是跨进程通信,通过Binder调用AMS的方法:
ActivityThread.java:
private void attach(boolean system, long startSeq)
final IActivityManager mgr = ActivityManager.getService();
try
mgr.attachApplication(mAppThread, startSeq);
catch (RemoteException ex)
throw ex.rethrowFromSystemServer();
进入ActivityManager.getService()方法
ActivityManager.java:
@UnsupportedAppUsage
public static IActivityManager getService()
return IActivityManagerSingleton.get();
@UnsupportedAppUsage
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;
;
AMS是继承自IActivityManager.Stub的
public class ActivityManagerService extends IActivityManager.Stub ...
--> ActivityThread--- attach 7336 跨进程调用AMS方法
mgr.attachApplication(mAppThread, startSeq);
此处传入的 mAppThread类型是ApplicationThread,它是ActivityThread的内部类
ApplicationThread extends IApplicationThread.Stub
AMS跨进程回调都会调到mAppThread里面,然后mAppTread 收到调用后,自己先处理下后直接通过ActivityThread的Handler发消息出去,然后ActivityThread在处理消息,这基本上是固定路数,这里先说明下,后续介绍会简化流程。
--->AMS:attachApplication 5446 5454
--->AMS:attachApplicationLocked 5023 5317
//跨进程回调到ActivityThread
thread.bindApplication(...)
这里的thread就是我们传入的mAppThread,现在又调回ActivityThread了,目的是什么呢?
答:是创建Application,我们继续看:
--->ActivityThread --- bindApplication 1036
--->ActivityThread --- bindApplication 1094
sendMessage(H.BIND_APPLICATION, data);
固定套路,收到AMS的回调先发个handler,这个handler是ActivityThread的一个内部类
//ActivityThread 316
final H mH = new H();
//ActivityThread 1803
class H extends Handler
...
我们直接到H类的 handleMessage方法里看看怎么处理的:
--->ActivityThread$H --- handleMessage 1907 1913
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
--->ActivityThread --- handleBindApplication 6372
--->ActivityThread --- handleBindApplication 6595 先把APP级别的的context创建好
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
--->ActivityThread --- handleBindApplication 6683 在创建 Application
app = data.info.makeApplication(data.restrictedBackupMode, null);
--->LoadedApk--- makeApplicatio 1196 1236
app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
--->Instrumentation--- newApplication 1154
--->Instrumentation--- newApplication 1159
app.attach(context);
--->Application --- attach(Context context) 350
--->Application --- attach(Context context) 351
attachBaseContext(context);
此处调用了Application的 attachBaseContext(context) 方法
---> ActivityThread 创建好后,回到ActivityThread,继续往下走到 6712 行
下面代码里初始化了ContentProvider
//ActivityThread.java
// 初始化Provider 这里也要注意下,调用application的onCreate方法之前就初始化ContentProvider了,这也是一些第三方框架(比如leakCanary)不需要初始化的原理,他们是通过ContentProvider来初始化的
installContentProviders(app, data.providers);
mInstrumentation.callApplicationOnCreate(app);
点进去:
//Instrumentation.java
public void callApplicationOnCreate(Application app)
app.onCreate();
此处调用了Application的 onCreate() 方法
这样Application就创建好了,接下来我们继续到AMS里面,继续往下走代码
--->接AMS:attachApplicationLocked 5023 5317
--->AMS:attachApplicationLocked 5374
didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
这里的mAtmInternal 是ActivityTaskManagerInternal,真正干活的是他的子类LocalService
LocalService是ActivityTaskManagerService(简称ATMS)的子类,应该9.0引入的ATMS,AMS把很多工作都委派给ATMS来做了。
--->ATMS --$LocalService.attachApplication 6884 6890
return mRootWindowContainer.attachApplication(wpc);
--->RootWindowContainer--attachApplication 1929
boolean attachApplication(WindowProcessController app) throws RemoteException
...
for (int displayNdx = getChildCount() - 1; displayNdx >= 0; --displayNdx)
final PooledFunction c = PooledLambda.obtainFunction(
RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
PooledLambda.__(ActivityRecord.class), app,
...
return didSomething;
这里面的startActivityForAttachedApplicationIfNeeded方法容易被漏掉,我们的流程要走到这里面,这是Android 11源码引入的 Android 10 还没有这个逻辑
--->RootWindowContainer--startActivityForAttachedApplicationIfNeeded1957
private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
WindowProcessController app, ActivityRecord top)
try
if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
true /*checkConfig*/))
mTmpBoolean = true;
catch (RemoteException e)
return false;
--->ActivityStackSupervisor -- realStartActivityLocked 718(Android10也会调到这个方法来)
--->ActivityStackSupervisor -- realStartActivityLocked 838 842
这里正式和step 2 b接轨
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);
final DisplayContent dc = r.getDisplay().mDisplayContent;
clientTransaction.addCallback(LaunchActivityItem.obtain(...));
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume)
lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
else
lifecycleItem = PauseActivityItem.obtain();
clientTransaction.setLifecycleStateRequest(lifecycleItem);
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
这个方法干了这么几件事:
- 构建ClientTransaction 对象
- 构建LaunchActivityItem对象
- 把 LaunchActivityItem通过 ClientTransaction addCallback方法加进去
- 构建ResumeActivityItem对象
- 把 ResumeActivityItem通过 ClientTransaction setLifecycleStateRequest方法加进去
- 最后一行通过ClientLifecycleManager scheduleTransaction方法执行ClientTransaction
这里的mService是ATMS,getLifecycleManager 得到的是ClientLifecycleManager
--->ClientLifecycleManager-- scheduleTransaction 45 47
void scheduleTransaction(ClientTransaction transaction) throws RemoteException
final IApplicationThread client = transaction.getClient();
transaction.schedule();
...
--->ClientTransaction -- schedule 135
public void schedule() throws RemoteException
mClient.scheduleTransaction(this);
这里的mClient还是mAppThread 所以又调到ActivityThread了
--->ActivityThread-- scheduleTransaction 1718 1719 这里最终调用的是ActivityThread父类的方法,父类是谁?答:是ClientTransactionHandler
--->ClientTransactionHandler-- scheduleTransaction 46
void scheduleTransaction(ClientTransaction transaction)
transaction.preExecute(this);
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
又是通过handler来发消息,那继续回到ActivityThread吧
--->ActivityThread$H-- handleMessage 2064
case EXECUTE_TRANSACTION:
final ClientTransaction transaction = (ClientTransaction) msg.obj;
mTransactionExecutor.execute(transaction);
break;
拿到ClientTransaction对象 然后通过mTransactionExecutor执行他
--->TransactionExecutor -- execute69 95
--->TransactionExecutor -- executeCallbacks 104 126
final ClientTransactionItem item = callbacks.get(i);
从ClientTransaction的callbacks中拿出 item 这是上面传入的LaunchActivityItem
--->TransactionExecutor -- executeCallbacks 135
item.execute(mTransactionHandler, token, mPendingActions);
调用其execute方法
--->LaunchActivityItem -- execute 78
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions)
client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
这里的client还是之前的mAppThread,所以继续到ActivityThread里去
--->ActivityThread -- handleLaunchActivity 3573 终于进入启动Activity的正题了,绕了一大圈~
--->ActivityThread -- handleLaunchActivity 3601
final Activity a = performLaunchActivity(r, customIntent);
--->ActivityThread -- performLaunchActivity 3330
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent)
//创建Activity的context
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try
//反射创建Activity
java.lang.ClassLoader cl = appContext.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)
if (!mInstrumentation.onException(activity, e))
throw new RuntimeException(
"Unable to instantiate activity " + component
+ ": " + e.toString(), e);
try
//执行attach
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor, window, r.configCallback,
r.assistToken);
//调用生命周期方法 onCreate
mInstrumentation.callActivityOnCreate(activity, r.state);
catch (SuperNotCalledException e)
throw e;
catch (Exception e)
return activity;
此方法干了这几件事:
- 创建Activity的Context
- 反射创建Activity
- 执行activity.attach
- 执行Activity的生命周期方法onCreate
--->Activity -- attach 7892
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor,
Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken)
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
mWindow = new PhoneWindow(this, window, activityConfigCallback);
mWindow.setWindowControllerCallback(mWindowControllerCallback);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED)
mWindow.setSoftInputMode(info.softInputMode);
if (info.uiOptions != 0)
mWindow.setUiOptions(info.uiOptions);
mUiThread = Thread.currentThread();
mMainThread = aThread;
mInstrumentation = instr;
mToken = token;
mAssistToken = assistToken;
mIdent = ident;
mApplication = application;
mIntent = intent;
mReferrer = referrer;
mComponent = intent.getComponent();
mActivityInfo = info;
mTitle = title;
mParent = parent;
mEmbeddedID = id;
mLastNonConfigurationInstances = lastNonConfigurationInstances;
if (voiceInteractor != null)
if (lastNonConfigurationInstances != null)
mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
else
mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
Looper.myLooper());
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
if (mParent != null)
mWindow.setContainer(mParent.getWindow());
mWindowManager = mWindow.getWindowManager();
mCurrentConfig = config;
mWindow.setColorMode(info.colorMode);
mWindow.setPreferMinimalPostProcessing(
(info.flags & ActivityInfo.FLAG_PREFER_MINIMAL_POST_PROCESSING) != 0);
setAutofillOptions(application.getAutofillOptions());
setContentCaptureOptions(application.getContentCaptureOptions());
此方法创建了PhoneWindow对象,并为其设置了WidowManager
--->ActivityThread -- performLaunchActivity 3422
mInstrumentation.callActivityOnCreate(activity, r.state);
这里触发Activity的生命周期 onCreate
--->接:TransactionExecutor -- execute方法 接着往下执行到97行
executeLifecycleState(transaction);
--->TransactionExecutor -- executeLifecycleState 152
private void executeLifecycleState(ClientTransaction transaction)
final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
这里的lifecycleItem就是前面放入的ResumeActivityItem,同样的套路,执行其execute方法
ResumeActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token,
PendingTransactionActions pendingActions)
client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
"RESUME_ACTIVITY");
这里的client还是之前的mAppThread,所以继续到ActivityThread里去(此套路似曾相识吧)
---> ActivityThread --- handleResumeActivity 4468
@Override
public void handleResumeActivity(...)
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (r.window == null && !a.mFinished && willBeVisible)
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
//先隐藏DecorView 等添加到window只后在展示出来
decor.setVisibility(View.INVISIBLE);
ViewManager wm = a.getWindowManager();
if (r.mPreserveWindow)
if (a.mVisibleFromClient)
if (!a.mWindowAdded)
a.mWindowAdded = true;
//把DecorView添加到window
wm.addView(decor, l);
else
else if (!willBeVisible)
if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
r.hideForNow = true;
if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow)
...
//使DecorView可见
if (r.activity.mVisibleFromClient)
r.activity.makeVisible();
---> ActivityThread --- handleResumeActivity 4476
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
---> ActivityThread --- performResumeActivity 4395
public ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
String reason)
final ActivityClientRecord r = mActivities.get(token);
try
//调用生命周期 onResume
r.activity.performResume(r.startsNotResumed, reason);
catch (Exception e)
return r;
---> Activity --- performResume 7919
final void performResume(boolean followedByPause, String reason)
dispatchActivityPreResumed();
performRestart(true /* start */, reason);
//调用生命周期方法 onResume
mInstrumentation.callActivityOnResume(this);
mFragments.dispatchResume();
mFragments.execPendingActions();
onPostResume();
if (!mCalled)
throw new SuperNotCalledException(
"Activity " + mComponent.toShortString() +
" did not call through to super.onPostResume()");
dispatchActivityPostResumed();
---> Activity --- performResume 7921 performRestart()
final void performRestart(boolean start, String reason)
if (mStopped)
//调用生命周期onRestart 在stop的情况下才会执行
mInstrumentation.callActivityOnRestart(this);
if (start)
//调用生命周期onStart
performStart(reason);
mInstrumentation.callActivityOnRestart(this);
这里有可能触发Activity生命周期onRestart (在stop的情况下)
---> Activity --- performStart 7819
final void performStart(String reason)
dispatchActivityPreStarted();
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
mFragments.noteStateNotSaved();
mCalled = false;
mFragments.execPendingActions();
//调用Activity生命周期 onStart
mInstrumentation.callActivityOnStart(this);
mInstrumentation.callActivityOnStart(this)
这里触发Activity的生命周期 onStart
---> 继续回到 Activity --- performResume 方法 往下执行到7939行
mInstrumentation.callActivityOnResume(this);
这里触发Activity的生命周期 onResume
---> 回到ActivityThread --- handleResumeActivity 方法 往下执行到4535行
wm.addView(decor, l);
wm-- addView 添加DecorView到window
WindowManager 是个接口 继承自 ViewManager 它的实现类是 WindowManagerImpl
---> WindowManagerImpl --- addView 107
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
...
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params)
mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow,
mContext.getUserId());
委托给 WindowManagerGlobal来处理了
---> WindowManagerGlobal--- addView 331
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow, int userId)
synchronized (mLock)
//创建ViewRootImpl 对象
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
try
//通过ViewRootImpl 的setView 方法完成view的添加在当前
//我们分析的场景里,这里的view是DecorView
root.setView(view, wparams, panelParentView, userId);
catch (RuntimeException e)
// BadTokenException or InvalidDisplayException, clean up.
if (index >= 0)
removeViewLocked(index, true);
throw e;
这里初始化了 ViewRootImpl 对象,这个对象非常关键,我们熟悉的requestLayout、invalidate、onMesure、onLayout、onDraw几个方法都与它有关系,它是我们和WindowManagerService(WMS)之间的中间人。
---> WindowManagerGlobal--- addView 409
root.setView(view, wparams, panelParentView, userId);
---> ViewRootImpl --- setView 919
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
int userId)
synchronized (this)
if (mView == null)
mView = view;
//关键方法1
requestLayout();
try
//关键方法2
res = mWindowSession.addToDisplayAsUser(...);
setFrame(mTmpFrame);
catch (RemoteException e)
//关键方法3
view.assignParent(this);
此方法里面有干了三件关键的事情:
- 调用requestLayout 可以触发所有view的onMesure、onLayout、onDraw方法的执行
- 调用mWindowSession.addToDisplayAsUser将窗口添加到指定的显示区域
- 通过view.assignParent(this);将DecorView的parent设置为自身(ViewRootImpl),所有普通view的getParent得到的是它的父类view,而DecorView getParent得到的是ViewRootImpl。
下面我们进入到requestLayout方法来看下怎么触发的view的onMesure、onLayout、onDraw方法:
---> ViewRootImpl --- requestLayout 1604
@Override
public void requestLayout()
if (!mHandlingLayoutInLayoutRequest)
checkThread();
mLayoutRequested = true;
scheduleTraversals();
---> ViewRootImpl --- scheduleTraversals 1923
void scheduleTraversals()
if (!mTraversalScheduled)
//发送一个消息同步屏障 挡住同步消息(目的是让优先级更高的异步消息先执行)
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
//将mTraversalRunnable添加到mChoreographer中等待执行
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
mChoreographer.postCallback 传入 mTraversalRunnable,等底层每16ms发来信号(60帧/s的手机)就会触发执行这个Runnable,界面刷新的消息是异步的handler消息,优先级最高。
我们看看这个mTraversalRunnable里面干了啥:
---> ViewRootImpl --- TraversalRunnable 1923
final class TraversalRunnable implements Runnable
@Override
public void run()
doTraversal();
---> ViewRootImpl --- doTraversal 1943
void doTraversal()
if (mTraversalScheduled)
//移除同步消息屏障
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
performTraversals();
---> ViewRootImpl --- performTraversals 2332
private void performTraversals()
host.dispatchAttachedToWindow(mAttachInfo, 0); 2417行
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec); 2880行
if (didLayout)
performLayout(lp, mWidth, mHeight); 2938行
if (!cancelDraw)
performDraw(); 3099行
else
此方法干了几件重要的事情:
- dispatchAttachedToWindow 此方法有两个重要功能
- 给所有view添加mAttachInfo信息
- 触发各个View在渲染之前的通过post或postDelay发送的的Runnable,这也是为什么我们调用View.post、postDelay方法可以不用关心view是否已经准备好的原因,因为准备好以后才会调用我们的任务。(如果view还没准备好,我们post发过来的任务会存在HandlerActionQueue类的队列里面)
- performMeasure -- 最终触发view onMesure方法
- performLayout -- 最终触发view onLayout方法
- performDraw -- 最新触发view onDraw方法
-->回到: ViewRootImpl --- setView 方法
此方法执行完毕后就差不多了,但是用户仍然还没看到界面,我们继续跟进:
-->回到ActivityThread --- handleResumeActivity 方法 继续往下执行到4587行
r.activity.makeVisible();
看方法名就知道要干啥了
-->Activity --- makeVisible
void makeVisible()
if (!mWindowAdded)
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
mDecor.setVisibility(View.VISIBLE);
mDecor.setVisibility(View.VISIBLE);
执行完此行后我们终于看到了界面!!!
如果你想知道我们在Activity onCreate方法里通过setContentView 传入的xml布局是如何被转换成view添加到DecorView的,可以看我的这篇文章:
最后用一个简短的执行步骤来总结下一个应用“从无到有”的生命线:
-
- SystemService进程--socket 通知Zygote进程 fork出 APP进程
- 调用其ActivityThread的main方法
- ActivityThread:main ---
- Looper.prepareMainLooper()
- ActivityThread thread = new ActivityThread();
- thread.attach(false, startSeq);
- final IActivityManager mgr = ActivityManager.getService();拿到 SS进程的AMS 后面跨进程调用AMS的方法
- mgr.attachApplication(mAppThread, startSeq);
- 2中传入的 mAppThread类型是ApplicationThread,它是ActivityThread的内部类,ApplicationThread extends IApplicationThread.Stub AMS跨进程回调都会调到mAppThread里面,然后mAppTread 收到调用后,自己先处理下后直接通过ActivityThread的Handler发消息出去,然后ActivityThread在处理消息
- Looper.loop();
- AMS:attachApplication
- ---attachApplicationLocked ---
- thread.bindApplication --
- ActivityThread---bindApplication 又调回APP进程的方法
- ---mH sendMessage(H.BIND_APPLICATION, data)
- ---handleBindApplication6372
- ---createAppContext6595
- --- data.info.makeApplication6683
- LoadedApk---makeApplication
- mActivityThread.mInstrumentation.newApplication1236
- Instrumentation.newApplication
- -- app.attach--Application attachBaseContext
- ActivityThread---mInstrumentation.callApplicationOnCreate 6712
- Application 生命周期 - onCreate
- 接AMS---attachApplicationLocked方法继续往下执行 ---
- mAtmInternal.attachApplication5374
- ATMS --$LocalService.attachApplication 注:LocalService extends ActivityTaskManagerInternal,终于找到它的实现类了~~~
- ATMS--mRootWindowContainer.attachApplication(wpc)6891,
- 注意Android 10(29)此处是这样实现的:mRootActivityContainer.attachApplication(wpc)
- RootWindowContainer--attachApplication--
- startActivityForAttachedApplicationIfNeeded1942 这个方法隐藏在参数里,难找
- --mStackSupervisor.realStartActivityLocked1965 api29也会调到这个方法
- ActivityStackSupervisor.java:realStartActivityLocked
- obtain一个ClientTransaction对象,然后addCallback方法,把LaunchActivityitem传进去clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent)
- clientTransaction.setLifecycleStateRequest(lifecycleItem); -- 这个是ResumeActivityItem
- 接着执行mService.getLifecycleManager().scheduleTransaction(clientTransaction);这里的mService是ATMS,atms初始化的时候创建的ClientLifecycleManager
- 触发clientTransaction 的 schedule方法 --- mClient.scheduleTransaction(this) mClient就是ActivityThead
- ActivityThead--scheduleTransaction -- 调到父类
- ClientTransactionHandler---scheduleTransaction --
- 通过子类ActivityThead mH发消息 sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);---
- ActivityThead---mTransactionExecutor.execute(transaction);
- TransactionExecutor --- executeCallbacks(transaction); 注意:在步骤n中传入了callBack 是LaunchActivityItem,所以接下来执行item.execute方法就是调用
- LaunchActivityItem --- execute方法
- 终于调到这里了client.handleLaunchActivity()---
- ActivityThread---handleLaunchActivity --- performLaunchActivity
- createBaseContextForActivity
- 反射创建Activity
- activity.attach
- attach方法中会初始化其成员变量,比如Context、Window、WindowManager、Application
- PhoneWindow就是在这里创建的
- callActivityOnCreate -- 触发Activity的生命周期 onCreate
- TransactionExecutor接步骤o 执行完execute(transaction)后
- ---executeLifecycleState(transaction);
- transaction.getLifecycleStateRequest() 这个是添加LauncherActivityItem的时候添加进去的ResumeActivityItem
- ResumeActivityItem -- execute
- client.handleResumeActivity
- ActivityThread--handleResumeActivity
- performResumeActivity
- Activity--performResume
- performRestart -- 在stop的情况下才会执行
- mInstrumentation.callActivityOnRestart(this);
- activity.onRestart() -- 触发Activity的生命周期 onRestart
- performStart
- mInstrumentation.callActivityOnStart(this);
- activity.onStart() -- 触发Activity的生命周期 onStart
- mInstrumentation.callActivityOnResume(this);-- 触发Activity的生命周期 onResume
- performRestart -- 在stop的情况下才会执行
- ActivityThread--handleResumeActivity -- 继续往下执行
- wm-- addView 添加DecorView到window
- WindowManagerImpl -- addView
- WindowManagerGlobal -- addView
- 创建ViewRootimpl
- ViewRootImpl -- setView 传入DecorView
- requestLayout
- scheduleTraversals
- mChoreographer.postCallback 传入 mTraversalRunnable
- 等底层每16ms发来信号(60帧/s的手机)就会触发执行这个Runnable
- TraversalRunnable -- doTraversal
- performTraversals
- dispatchAttachedToWindow 给所有view添加mAttachInfo信息
- 触发各个View在渲染之前的通过post或postDelay发送的的Runnable
- performMeasure -- 最终触发view onMesure方法
- performLayout -- 最终触发view onLayout方法
- performDraw -- 最新触发view onDraw方法
- view.assginParent(this) 这里的view是DecorView 所以DecorView的parent是ViewRootImpl
- addWindowToDIsplay 把window添加到指定的显示区域
- requestLayout
- ActivityThread--handleResumeActivity -- 继续往下执行
- r.activity.makeVisible();
- Activity
- mDecor.setVisibility(View.VISIBLE);;-- 用户终于看到界面了!!!
- SystemService进程--socket 通知Zygote进程 fork出 APP进程
以上是关于Android 11(platfrom 30)APP启动流程(含Activity)核心点记录的主要内容,如果未能解决你的问题,请参考以下文章
来自带有 API 30 (android 11) 的三星物理模拟器的错误 Android 11 -> java.net.SocketTimeoutException