原文: Android中Activity启动过程探究 https://www.cnblogs.com/kross/p/4025075.html
这篇文章是对上面文章的总结
1.因为Android也是 Java程序,所以 必然有一个Main方法入口,这个入口,就是在ActivityThread中,因此首先 调用android.app.ActivityThread.main()方法
2.在ActivityThread中有一个继承于Handler的内部类,名叫H,这个H结合Looper和MessageQuene等用于ActivityThread这个主线程的消息处理机制,在H的handleMessage()方法中,有个LAUNCH_ACTIVITY的what值,从字面意思来看就是启动Activity的意思,这个分支下又调用了android.app.ActitityThread.handleLaunchActivity(), 如下图
3.handleLaunchActivity()方法中又先后调用了preformLaunchActivity() 和 handleResumeActivity(),并且preformLaunchActivity()方法生成了Activity对象,在判断Activity对象不等于null的情况下,接着调用了 handleResumeActivity()
3.1 preformLaunchActivity()方法:其中mInstrumentation.callActivityOnCreate(activity, r.state)则是调用了Activity的onCreate方法,Activity的生命周期方法都是由Instrumentation对象来调用的。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
...
Activity activity = null;
try {
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
//生成一个Activity对象
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
...
} catch (Exception e) {
//抛出异常 Unable to instantiate activity
}
try {
...
if (activity != null) {
...
//
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config);
...
//调用Activity的onCreate方法,Activity的生命周期方法都是由Instrumentation对象来调用的。
mInstrumentation.callActivityOnCreate(activity, r.state);
}
}
...
}
3.2 android.app.activity.attach()方法
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) {
attachBaseContext(context);
mFragments.attachActivity(this, mContainer, null);
//生成一个Window对象
mWindow = PolicyManager.makeNewWindow(this);
//设置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();
mCurrentConfig = config;
}
3.3 接下来mInstrumentation.callActivityOnCreate(activity, r.state),就执行了Activity的setContentView方法了,可以参考另外一片文章:https://blog.csdn.net/jinchen_boke/article/details/88351987
4.android.app.ActivityThread.handleResumeActivity()方法,这个方法在ViewRootImpl的分析中也有,如下
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
boolean reallyResume) {
...
//生成了一个ActivityClientRecord对象
//方法内部其实是 通过Instrumentation调用Activity的onResume()方法。
ActivityClientRecord r = performResumeActivity(token, clearHide);
if (r != null) {
final Activity a = r.activity;
...
if (r.window == null && !a.mFinished && willBeVisible) {
r.window = r.activity.getWindow();
View decor = r.window.getDecorView();
decor.setVisibility(View.INVISIBLE);
//父类引用指向子类对象,WindowManager是继承于ViewManager的
//这个实现其实WindowManagerImpl,而WindowManagerImpl的实现里
//又调用了WindowManagerGlocal这个类的方法,如增删改View这些方法
ViewManager wm = a.getWindowManager();
WindowManager.LayoutParams l = r.window.getAttributes();
a.mDecor = decor;
l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
l.softInputMode |= forwardBit;
if (a.mVisibleFromClient) {
a.mWindowAdded = true;
//WindowManager添加decorView
//这个地方底层其实就是调用了WindowManagerGlocal的addView了。
wm.addView(decor, l);
}
...
}
...
}
}
WindowManagerGlocal的addView,如下,可以看出WindowManagerGlocal的addView其实是调用了ViewRootImpl的setView
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);
// do this last because it fires off messages to start doing things
try {
//ViewRootImpl的setView
root.setView(view, wparams, panelParentView);
} catch (RuntimeException e) {
...
throw e;
}
}
ViewRootImpl 的setView
/**
* We have one child
*/
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
synchronized (this) {
if (mView == null) {
mView = view;
...
// Schedule the first layout -before- adding to the window
// manager, to make sure we do the relayout before receiving
// any other events from the system.
requestLayout();
...
view.assignParent(this);
...
}
}
}
android.view.ViewRootImpl.requestLayout()方法 如下图
android.view.ViewRootImpl.scheduleTraversals()方法,如下图
在mTraversalRunnable 的 run方法中,调用了doTraversal()方法。而doTraversal()方法又调用了performTraversals()方法,这个方法非常长,依次调用了performMeasure(),performLayout(),performDraw()三个方法,进行的View的绘制。