Potato
Potato copied to clipboard
Activity: Lifecycle and ActivityThread
Activity: Lifecycle and ActivityThread
[TOC]
之前说了 App 的大概启动流程,在 Launcher 进程也是通过 startActivity 方法启动 Activity。经过一系列进程创建,Application 初始化之后,MainActivity.onCreate() 方法将会执行,这篇文章就从开始入手分析。
onCreate 过程
ActivityThread.handleLaunchActivity
启动 Activity 的整个过程最终都会调用该方法,部分代码和注释如下:
// 当Server 请求启动或者重启时,实现 Activity 的启动,
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, Intent customIntent) {
// 创建 Activity
final Activity a = performLaunchActivity(r, customIntent);
return a
}
// 启动 Activity 和核心方法
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// AndroidManifest 中关于 Activity 的相关信息
ActivityInfo aInfo = r.activityInfo;
// loadedApk 对象,表示 apk 在内存的所有信息表示
if (r.packageInfo == null) {
r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
Context.CONTEXT_INCLUDE_CODE);
}
// application 中确定唯一的四大组件的类,由 package 名和 class 名两个因素封装而成。
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);
}
// 上下文对象
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
try {
// 类加载器
java.lang.ClassLoader cl = appContext.getClassLoader();
// 创建 Activity
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
}
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (activity != null) {
// 将一系列字段传入 Activity
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);
if (customIntent != null) {
activity.mIntent = customIntent;
}
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
// 调用 Activity.onCreate()
mInstrumentation.callActivityOnCreate(activity, r.state);
}
return activity;
}
上面代码有删减,到此为止,MainActivity.onCreate() 方法已经执行,看一下其中的 activity.attach() 方法,
主要是 PhoneWindow 和对应 WindowManger 对象的设置
final void attach(...) {
// 创建 PhoneWindow 对象
mWindow = new PhoneWindow(this, window, activityConfigCallback);
// 设置 windowManager
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();
}
回到 Activity.onCreate() 方法:
// Instrumentation
public void callActivityOnCreate(Activity activity, Bundle icicle) {
prePerformCreate(activity);
activity.performCreate(icicle);
postPerformCreate(activity);
}
// Activity
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
// 执行 onCreate
if (persistentState != null) {
onCreate(icicle, persistentState);
} else {
onCreate(icicle);
}
// fragment 的生命周期
mFragments.dispatchActivityCreated();
// 转换动画
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
}
@MainThread
@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
// 恢复保存的数据,如果有的话
if (savedInstanceState != null) {
mAutoFillResetNeeded = savedInstanceState.getBoolean(AUTOFILL_RESET_NEEDED, false);
mLastAutofillId = savedInstanceState.getInt(LAST_AUTOFILL_ID,
View.LAST_APP_AUTOFILL_ID);
if (mAutoFillResetNeeded) {
getAutofillManager().onCreate(savedInstanceState);
}
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.fragments : null);
}
// fragment 生命周期回调
mFragments.dispatchCreate();
// ActivityLifecycleCallbacks 回调
getApplication().dispatchActivityCreated(this, savedInstanceState);
if (mVoiceInteractor != null) {
mVoiceInteractor.attachActivity(this);
}
mRestoredFromBundle = savedInstanceState != null;
mCalled = true;
}
在以上代码和部分注释的分析中,Activirty 完成了创建,同时创建了 PhoneWindow。紧接着就需要手动调用setContentView() 方法设置布局。
setContentView
// 设置 Activity 的显示内容,位于最上面
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
// 设置 actionbar
initWindowDecorActionBar();
}
// PhoneWindow.java
@Override
public void setContentView(int layoutResID) {
// window 要放置的view,Decor 或者其子view
if (mContentParent == null) {
// 初始化 WindowDecor,是 window 最上层的 view,并包含 Decor。
installDecor();
} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
mContentParent.removeAllViews();
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
getContext());
transitionTo(newScene);
} else {
// 从 xml 布局中创建 view, 添加到 parent
mLayoutInflater.inflate(layoutResID, mContentParent);
}
mContentParent.requestApplyInsets();
final Callback cb = getCallback();
if (cb != null && !isDestroyed()) {
// 内容改变的回调
cb.onContentChanged();
}
mContentParentExplicitlySet = true;
}
在 mLayoutInflater.inflate(layoutResID, mContentParent); 中有两个特别重要的地方,代码如下:
// 忽略 Xml 解析内容的部分,看下关键代码
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
synchronized (mConstructorArgs) {
try {
// merge 节点,tag
if (TAG_MERGE.equals(name)) {
if (root == null || !attachToRoot) {
throw new InflateException("<merge /> can be used only with a valid "
+ "ViewGroup root and attachToRoot=true");
}
// 递归方法,用于向下传递xml层次结构并实例化视图、实例化其子视图,然后调用onfinishinflation()。
rInflate(parser, root, inflaterContext, attrs, false);
} else {
// Inflate all children under temp against its context.
// 与上面一样,除了 parent, 见下
rInflateChildren(parser, temp, attrs, true);
}
return result;
}
}
final void rInflateChildren(XmlPullParser parser, View parent, AttributeSet attrs,
boolean finishInflate) throws XmlPullParserException, IOException {
rInflate(parser, parent, parent.getContext(), attrs, finishInflate);
}
void rInflate(XmlPullParser parser, View parent, Context context,
AttributeSet attrs, boolean finishInflate) throws XmlPullParserException, IOException {
// 节点深度
final int depth = parser.getDepth();
int type;
boolean pendingRequestFocus = false;
// 判断何时结束
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
// 获取 view 名字
final String name = parser.getName();
if (TAG_REQUEST_FOCUS.equals(name)) {
pendingRequestFocus = true;
consumeChildElements(parser);
} else if (TAG_TAG.equals(name)) {
parseViewTag(parser, parent, attrs);
// include tag
} else if (TAG_INCLUDE.equals(name)) {
if (parser.getDepth() == 0) {
throw new InflateException("<include /> cannot be the root element");
}
parseInclude(parser, context, parent, attrs);
// merge tag
} else if (TAG_MERGE.equals(name)) {
throw new InflateException("<merge /> must be the root element");
} else {
// 普通的 view 实力化
final View view = createViewFromTag(parent, name, context, attrs);
final ViewGroup viewGroup = (ViewGroup) parent;
final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
// 循环,知道结束
rInflateChildren(parser, view, attrs, true);
viewGroup.addView(view, params);
}
}
if (pendingRequestFocus) {
parent.restoreDefaultFocus();
}
// 结束
if (finishInflate) {
parent.onFinishInflate();
}
}
在这个部分,两个函数循环调用,直到 xml 中所有的 View 解析完毕,调用 parent.onFinishInflate() 方法,完成整个过程。
start 过程
//ActivityThread
@Override
public void handleStartActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions) {
// 没有经过 stop ,不能start
if (!r.stopped) {
throw new IllegalStateException("Can't start activity that is not stopped.");
}
// Start
// 处理start 过程
activity.performStart("handleStartActivity");
// 设置状态
r.setState(ON_START);
}
// Activity
final void performStart(String reason) {
// 调用 Activity.start 方法
mInstrumentation.callActivityOnStart(this);
mFragments.dispatchStart();
mFragments.reportLoaderStart();
}
resume 过程
@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
String reason) {
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
// 先将 decor 置为不可见
decor.setVisibility(View.INVISIBLE);
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) {
}
if (a.mVisibleFromClient) {
if (!a.mWindowAdded) {
a.mWindowAdded = true;
// 将 Decor 加入到 window 中
wm.addView(decor, l);
} else {
// 添加过就通知改变
a.onWindowAttributesChanged(l);
}
}
r.activity.mVisibleFromServer = true;
mNumVisibleActivities++;
if (r.activity.mVisibleFromClient) {
// 设置可见
r.activity.makeVisible();
}
}
}
这个函数中, 首先是调用 performResumeActivity,使 Activity 进入 resume 状态。接着将 DecorView 添加到 Window 中并显示出来。
wm.addView()
下面来看一下这个过程。
// 从 activity 中添加或者移除 view
public interface ViewManager
{
public void addView(View view, ViewGroup.LayoutParams params);
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
public void removeView(View view);
}
真正的实现在 WindowMangerImpl 中。
// WindowMangerImpl.java
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
// WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params,
Display display, Window parentWindow) {
...
root = new ViewRootImpl(view.getContext(), display);
view.setLayoutParams(wparams);
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
try {
root.setView(view, wparams, panelParentView);
}
...
}
在 WindowMangerGlobal 中保存了一系列 ViewRootImpl 实例。每增加一个布局,就会创建一个 ViewRootimpl 对象。
//
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if(mView != null) {
...
requestLayout();
}
}
@Override
public void requestLayout() {
if (!mHandlingLayoutInLayoutRequest) {
checkThread();
mLayoutRequested = true;
scheduleTraversals();
}
}
// 线程检查:只有在 onResume 之后,Activity 才会在检查是否在 UI 线程更新 UI。
void checkThread() {
if (mThread != Thread.currentThread()) {
throw new CalledFromWrongThreadException(
"Only the original thread that created a view hierarchy can touch its views.");
}
}
在上面的过程中,最终会执行到 ViewRootImpl.performTraversals() 方法,后面就是 View 的绘制流程。
总结
这篇文章主要接着 App 的启动,分析 Application 创建之后,ActivityThread 和 Instumentation 控制执行 Activity 生命周期方法的流程,从 create, start 到 resume,中间与 fragment 和相关生命周期等。