之前只知道activity的生命周期, 不懂start, resume等在什么时候调用的, 还有第一次layout是什么时候.. 于是有了下面的记录:
一切从ActivityThread开始, ActivityThread 中的private Activity performLaunchActivity (ActivityClientRecord r,Intent customIntent) 启动一个activity.
ActivityThread里有 final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
1. handleMessage
ActivityThread里handleMessage(msg), 如果message是LAUNCH_ACTIVITY, 执行:
final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
ActivityClientRecord是一个结构体, 里边有window, activity, parent, paused, stopped等.
然后调用handleLaunchActivity
2. handleLaunchActivity
先调用 WindowManagerGlobal.initialize()
然后调用performLaunchActivity, 见3
然后调用handleResumeActivity, 见4
3. performLaunchActivity
这里private Activity performLaunchActivity里, 根据已有参数, new一个activity, 然后调用:
Context appContext = createBaseContextForActivity(r,activity); 初始化context, 见3.0
activity.attach(appContext, ... ) 见 3.1
activity.performStart()
3.0. createBaseContextForActivity
ContextImpl appContext =ContextImpl.createActivityContext(this, r.packageInfo,displayId, r.overrideConfig);
相当于new 一个ContextImpl.
3.1 Activity.attach()
attachBaseContext(context):
先生成mWindow, mWindow = new PhoneWindow();
mWindow.setCallback(this); 将mWindow中的mCallback设置为当前activity
然后调用mWindow的setWindowManager. 见3.2
mUiThread = Thread.currentThread() Thread.currentThread() 是指获取当前运行的线程对象
mMainThread= aThread;
3.2 Window.setWindowManager(WindowManager wm)
在window里面,会有一个WindowManager类型的成员叫做mWindowManager,它是在setWindowManager()里通过WindowManagerService这个binder通过远程调用来创建的一个WindowManagerImpl,而这个WindowManagerImpl内部会通过一个static的WindowManagerGlobal去做所有跟WindowManager有关的操作。 简而言之就是,activity中有个window,window中通过mGlobal来跟WMS交互。
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
createLocalWindowManager 就是 return一个新的new WindowManagerImpl(mDisplay,parentWindow);
4. handleResumeActivity
先调用performResumeActivity(这里主要调activity的performResume)
然后获得 window, decor,调用 decor的setvisibility, 然后Windowmanager的addView: wm.addView(decor,l); 见5
5. addView
WindowManager的addView是在WindowManagerGlobal里实现的:
new一个ViewRootImpl root; 然后最终调用: (这里的root是ViewRootImp, view是activity的decor)
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
然后:
root.setView(view) 见6
WindowsManagerGlobal里有重要的成员变量:
ArrayList<View> mViews = new ArrayList<View>();
ArrayList<ViewRootImp> mRoots = new ArrayList<ViewRootImpl>();
ArrayList<WindowManager.LayoutParams> mParams = new ArrayList<WindowManager.LayoutParams>
6. setView
终于到ViewRootImp了.
setView主要做的是:
mAttachInfo.mRootView= view;
mView= view;
mAdded=true;
// 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();
后来requestLayout呢, 里边就是调用checkThread, 然后scheduleTraversals
7. 附:
VIew的 onWindowFocusChanged , 说明是这样的:
/**
* Called when the window containing this view gains or loses focus. Note
* that this is separate from view focus: to receive key events, both
* your view and its window must have focus. If a window is displayed
* on top of yours that takes input focus, then your own window will lose
* focus but the view focus will remain unchanged.
*
*@paramhasWindowFocusTrue if the window containing this view now has
* focus, false otherwise.
*/
我猜: 所以是指的这个Window焦点变化, 而一个activity只有一个window, 它上面的任何一个view的这个方法都一样
Activity的onWindowFocusChanged:
* Called when the current {@linkWindow} of the activity gains or loses
* focus. This is the best indicator of whether this activity is visible
* to the user. The default implementation clears the key tracking
* state, so should always be called.
网友评论