Activity启动过程分析
原文: 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的绘制。
更多相关文章
- activity中onSaveInstanceState方法调用时机详解
- Android 利用getIdentifier()方法获取资源ID
- Android cursor query方法详解
- Android JNI和NDK学习(09)--JNI实例二 传递类对象
- 手动root android 模拟器(emulator)详细过程
- [置顶] Android系统安全之旅 第1章 编译Android程序的方法
- 【Android】View绘制过程分析之draw