Activity的创建流程

在TransactionExecutor顺序调用了Activity全部生命周期:参考博客:(21条消息) Android | 基于Android9.0的startActivity流程分析(3):新Activity的onStart流程、onResume流程_明朗晨光的专栏-CSDN博客

先来看execute(ClientTransaction transaction)方法:

1
2
3
4
5
public void execute(ClientTransaction transaction) {
executeCallbacks(transaction);

executeLifecycleState(transaction);
}

在看看execteLifecycleState方法:

1
2
3
4
5
6
7
8
/** Transition to the final state if requested by the transaction. */
private void executeLifecycleState(ClientTransaction transaction) {
// Cycle to the state right before the final requested state.
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
// Execute the final transition with proper parameters.
lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}

在看cycleToPath方法:

1
2
3
4
5
6
7
8
9
10
11
12
private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
ClientTransaction transaction) {
final int start = r.getLifecycleState();
if (DEBUG_RESOLVER) {
Slog.d(TAG, tId(transaction) + "Cycle activity: "
+ getShortActivityName(r.token, mTransactionHandler)
+ " from: " + getStateName(start) + " to: " + getStateName(finish)
+ " excludeLastState: " + excludeLastState);
}
final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
performLifecycleSequence(r, path, transaction);
}

再看performLifecycleSequence方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
ClientTransaction transaction) {
final int size = path.size();
for (int i = 0, state; i < size; i++) {
switch (state) {
case ON_CREATE:
mTransactionHandler.handleLaunchActivity(r, mPendingActions,
null /* customIntent */);
break;
case ON_START:
mTransactionHandler.handleStartActivity(r, mPendingActions);
break;
case ON_RESUME:
mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
break;
case ON_PAUSE:
mTransactionHandler.handlePauseActivity(r.token, false /* finished */,
false /* userLeaving */, 0 /* configChanges */, mPendingActions,
"LIFECYCLER_PAUSE_ACTIVITY");
break;
case ON_STOP:
mTransactionHandler.handleStopActivity(r.token, false /* show */,
0 /* configChanges */, mPendingActions, false /* finalStateRequest */,
"LIFECYCLER_STOP_ACTIVITY");
break;
case ON_DESTROY:
mTransactionHandler.handleDestroyActivity(r.token, false /* finishing */,
0 /* configChanges */, false /* getNonConfigInstance */,
"performLifecycleSequence. cycling to:" + path.get(size - 1));
break;
case ON_RESTART:
mTransactionHandler.performRestartActivity(r.token, false /* start */);
break;
default:
throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
}
}
}

可以看到 依次完成了 Activity的全部生命周期的调用。mTransactionHandler的对象是ClientTransactionHandler,这个类是一个抽象类,他的唯一实现类是ActivityThread。当调用到ActivityThread的handleLaunchActivity的时候,在handlerLaunchActivity里面调用了performLaunchActivity创建了Activity对象,并完成了Activity的onCreate()。

Activity对象的创建是在ActivityThread里面的performLaunchActivity方法:

1
2
3
4
5
6
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent){
Activity activity = null;
java.lang.ClassLoader cl = appContext.getClassLoader();
activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
return activity
}

首先在performLaunchActivity里面完成了Activity对象的创建。

在看这串代码会发现一个很好的东西Instrumentation,Activity对象的实例话是通过它进行的,Activity的create方法也是最先由它调用的。

1
2
3
4
5
6
7
8
9
10
11
12
Activity对象的实例化
public Activity newActivity(ClassLoader cl, String className,
Intent intent)
return activity;
}
Activity的create调用
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}

接着调用了activity的attach方法:

1
2
3
4
5
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);

在attach里面做了很多重要的事情:

  • 在performLaunchActity的时候并没给我们的Activity父类的mBase:Context赋值,赋值的地方就是在attach的时候。
  • 创建PhoneWindow对象。
  • 指定ui线程为当前Activity所在的线程
  • 给PhoneWindow设置WindowManager 也就是WindowManagerImpl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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); //给父类的mBase:Context赋值
mWindow = new PhoneWindow(this, window, activityConfigCallback);
if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
// 当软件盘的状态被指定了,则将软键盘状态设置为给定的
mWindow.setSoftInputMode(info.softInputMode);
}
mUiThread = Thread.currentThread();//指定ui线程为当前线程
// 给每个Activity的PhoneWindow创建WindowManagerImpl对象。
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
}

为什么要通过服务的方式获取WindManagerService,服务创建的WindowManagerService一样吗?

Activity通过执行attach方法,创建了Activity的Window对象,指定了ui线程,给window对象设置了WindowManagerIml。 一个Activity有一个window变量 一个mWindowManager变量 然后Winodw里面又保存了WindowManager对象。WindowManager里面由保存了window对象。

在performLaunchActivity()里面接着调用了callActivityOnCreate方法,去完成Activity的调用。

1
2
3
4
5
6
7
// 判断当前activity是不是数据持久化 
// 在Manifest里面申明 android:persistableMode="persistAcrossReboots"
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
  • 调用prePerformCreate(Activity)的时候往消息队列里面添加了一个启动activity的消息。

  • 然后activity调用performCreate去创建Activity

    这里没搞懂,为啥要往消息队列里面添加一个消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
// 启动Acitivity的时候往MessageQueue里面添加了一个消息
private void prePerformCreate(Activity activity) {
if (mWaitingActivities != null) {
synchronized (mSync) {
final int N = mWaitingActivities.size();
for (int i=0; i<N; i++) {
final ActivityWaiter aw = mWaitingActivities.get(i);
final Intent intent = aw.intent;
if (intent.filterEquals(activity.getIntent())) {
aw.activity = activity;
// 往消息队列里面添加一个消息
mMessageQueue.addIdleHandler(new ActivityGoing(aw));
}
}
}
}
}

现在来看Activity的performCreate方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
// 遍历调用全部有注册监听activity创建的监听
dispatchActivityPreCreated(icicle);
mCanEnterPictureInPicture = true;
restoreHasCurrentPermissionRequest(icicle);
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate");
mActivityTransitionState.readState(icicle);

mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
com.android.internal.R.styleable.Window_windowNoDisplay, false);
mFragments.dispatchActivityCreated(); // 这里也去调用了Fragment的创建流程
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
// 遍历调用全部注册有监听activty的postcreate监听
dispatchActivityPostCreated(icicle);
}

通过看源码,我们知道了另外一种用来全局监听activity状态的方式:就是在Application里面注册监听:

Application里面有个一公开接口 ActivityLifecycleCallbacks,我们可以站在全局的角度上观察所有activut的情况,使用方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MainApplication : BaseApplication() {
override fun onCreate() {
registerActivityLifecycleCallbacks(object :ActivityLifecycleCallbacks{
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}

override fun onActivityStarted(activity: Activity) {}

override fun onActivityResumed(activity: Activity) {}

override fun onActivityPaused(activity: Activity) {}

override fun onActivityStopped(activity: Activity) {}

override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}

override fun onActivityDestroyed(activity: Activity) {}
})
}
}
至此走完了Activity生命周期的所有方法。

ActivityTaskManagerService.java

1
2
3
// 实现了转场动画
public void overridePendingTransition(IBinder token, String packageName,
int enterAnim, int exitAnim)

一个Activity的创建首先在Activity的attach里面创建了PhoneWindow对象。

在调用到Activity的onCreate方法时候,将attach里面创建的PhoneWindow对象传递给了AppCompatDelegate里面的mWindow对象。

1
2
3
4
5
6
// AppCompatDelegate
@Override
public void onCreate(Bundle savedInstanceState) {
ensureWindow();
mCreated = true;
}

接着我们在onCreate里面调用setContentView(int layoutId)方法。

​ 执行逻辑是:在setContentView里面给我们的PhoneWindow创建了DecorView对象,然后拿到PhoneWindow里面的content父控件,然后将自己的view通过add的方式添加到这个content的view里面。

1
2
3
4
5
6
7
8
9
10
11
12
13
// AppCompatActivity
public void setContentView(@LayoutRes int layoutResID) {
getDelegate().setContentView(layoutResID);
}
// AppCompatDelegateImpl
@Override
public void setContentView(View v) {
ensureSubDecor(); //创建我们DecorView mSubDecor
ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content);
contentParent.removeAllViews();
contentParent.addView(v);
mAppCompatWindowCallback.getWrapped().onContentChanged();
}

现在来看下这个DecorView是怎么创建的:

1
2
3
4
5
6
7
8
9
10
11
// AppCompatDelegateImpl
private void ensureSubDecor() {
if (!mSubDecorInstalled) {
// 创建DecorView
mSubDecor = createSubDecor();
}
}
private ViewGroup createSubDecor() {


}

上面走完了Activity的onCreate方法,现在看下onStart执行流程。

在ActivityThread的handleStartActivity(ActivityClientRecord r,PendingTransactionActions pendingActions):

1
2
3
4
5
6
7
8
9
10
11
12
//  ActivityThread
public void handleStartActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions) {
final Activity activity = r.activity;
// Start
activity.performStart("handleStartActivity");
r.setState(ON_START);
}
// Activity
final void performStart(String reason) {
mInstrumentation.callActivityOnStart(this); //执行了Activity的start方法
}

上面走完了onStart方法。也没干什么


现在来看下onResume的执行流程:

在onResume里面干了最重要的事就是创建ViewRootImpl对象。

首先通过Activity获取对应的WindowManager。Activity的WindowManger对象是在Activity的attach放里面创建的。可以看上面的文章写了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// ActivityThread
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
// 这里执行了Activity的onResume 方法
final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
// 获取在attach的时候创建的WindowManager对象
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (r.mPreserveWindow) {
a.mWindowAdded = true;
r.mPreserveWindow = false;
// 第一次执行onResume的时候这里获取的是null
ViewRootImpl impl = decor.getViewRootImpl();
if (impl != null) {
impl.notifyChildRebuilt();
}
}
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
// 这里很关键,去创建了我们的ViewRootImpl
// 也将我们的DecorView添加到Window里面。
wm.addView(decor, l);
} else {
a.onWindowAttributesChanged(l);
}
}
......省略代码
}

再来看看刚才添加Decorview到Window的操作:

1
2
3
4
5
6
7
8
9
10
if (!a.mWindowAdded) {
a.mWindowAdded = true;
wm.addView(decor, l);
}
// WindowManagerImpl
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}

可以看到,WindowManagerImpl将添加view的操作交给了WindowManagerGlobal去做。

现在来看下WindowManagerGlobal是如何添加的:

1
2
3
4
//首先看下WindowManagerGlobal是怎么创建的:
// 可以看到他是透过懒加载的方式,创建了一个单例对象。
// 也就是说我们每个Activity的创建走的都是同一个对象。
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// WindowManagerGlobal
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
ViewRootImpl root;
View panelParentView = null;
// 创建了我们的ViewRootImpl
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
try {
// 开始一个view从测量到布局的整个流程。
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
if (index >= 0) {
removeViewLocked(index, true);
}
throw e;
}
}
}

Android 应用框架中为了更快的响应UI刷新事件在 ViewRootImpl.scheduleTraversals 中使用了同步屏障。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
int userId) {
requestLayout(); //可以看到ViewRootImpl主动调用了requestlayout
}
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();// 按计划进行分发
}
}

final ViewRootHandler mHandler = new ViewRootHandler();
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();
void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
// 通过postSyncBarrier()设置同步屏障 目的是为了让绘制流程更快的被执行
mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
//handler发送消息,有了同步屏障mTraversalRunnable就会被优先执行。
mChoreographer.postCallback(
Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
}
}

可以看到这里使用了消息机制里面的 同步屏障 机制。目的是为了让绘制流程尽快被执行。

设置同步屏障之后,next函数里面会忽略所有的同步消息,返回异步消息。换句话说就是Handler消息机制增加了一种简单的预先级制度,异步消息的优先级高于同步消息。

同步屏障就是将新的这个message插入到了表头的位置。

文章:Android中同步屏障的应用及简析 - 简书 (jianshu.com)

博客:《Android消息机制》

在mTraversalRunnable里面执行整个view的测量布局绘制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// ViewRootImpl
final TraversalRunnable mTraversalRunnable = new TraversalRunnable();final class TraversalRunnable implements Runnable {
@Override
public void run() {
doTraversal(); // 执行了全部的测量绘制布局过程
}
}

void doTraversal() {
if (mTraversalScheduled) {
mTraversalScheduled = false;
// 移除同步锁
mHandler.getLooper().getQueue().removeSyncBarrier(mTraversalBarrier);
performTraversals(); // 执行了全部的测量绘制布局过程
}
}

private void performTraversals() {
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
performLayout(lp, mWidth, mHeight);
performDraw();
}
private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}

计算的时候先进入到 View的measure方法:

1
2
// 将大小和方式融合在一起
makeMeasureSpec(int size,int mode)
1
2
3
4
5
6
7
8
9
// View.java
public final void measure(int widthMeasureSpec, int heightMeasureSpec) {
onMeasure(widthMeasureSpec, heightMeasureSpec);
}
// 给我们的view设置指定大小
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
}

当时viewGroup的时候,都是重载了onMeasure方法。因为我们还需要计算viewgroup里面的子view的大小,才能确定我们的viewgroup的大小是多少。

这里我们来看下LinearLayout的onMeasure方法:

1
2
3
4
5
6
7
8
9
// LinearLayout
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mOrientation == VERTICAL) {
measureVertical(widthMeasureSpec, heightMeasureSpec);
} else {
measureHorizontal(widthMeasureSpec, heightMeasureSpec);
}
}

总结: 一个view的测量过程都是首先通过view的measure执行下去,然后不同的view通过重写onMeasure方法实现对他们所有子view的测量。

上面就是从ViewRootImpl触发整个页面的执行测量的过程。


ViewRootImpl:performLayout()

1
2
3
4
5
6
7
8
9
// ViewRootImpl  
private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
int desiredWindowHeight) {
host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
}
// View
public void layout(int l, int t, int r, int b) {
onLayout(changed, l, t, r, b);
}

通过查看源代码,发现可以使用 addOnLayoutChangeListener()方法,监听某个view布局的改变。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
viewpager.addOnLayoutChangeListener(object :View.OnLayoutChangeListener{
override fun onLayoutChange(
v: View?,
left: Int,
top: Int,
right: Int,
bottom: Int,
oldLeft: Int,
oldTop: Int,
oldRight: Int,
oldBottom: Int
) {
// 知道了开始位置 和 结束位置 不就可以做动画了嘛
}
})

至此 layout分析完了


performDraw