第二阶段、应用进程侧的处理,主要是ViewTree的遍历。
接着第一段的最后调用:app.thread.scheduleLaunchActivity();这里的.thread是ApplicationThread,它是应用进程跟AMS通信的桥梁,AMS会通过:app.makeActive(mSystemThread.getApplicationThread(),mProcessStats);把应用线程中ApplicationThread对象赋值给进程中的IApplicationThread thread对象。
/* ActivityThread.java */
public final void scheduleLaunchActivity(){
//发LAUNCH_ACTIVITY给主线程的Handler,进而走到handleLaunchActivity
sendMessage(H.LAUNCH_ACTIVITY,r);
}
Step1、private voidhandleLaunchActivity(){
内部分下面两个子过程
Activitya = performLaunchActivity(r, customIntent);
handleResumeActivity(r.token,false, r.isForward,…);
}
performLaunchActivity的主要任务是生成一个Activity对象,然后调用它的attach方法,接着间接调用Activity的onCreate方法。
private Activity performLaunchActivity(){
//通过类加载器,加载这个Activity对象
activity= mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
//这个attach方法会为很多的全局变量赋值,比较重要的是mWindow
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)
//最终会调用Activity的oncreate方法
mInstrumentation.callActivityOnCreate(activity,r.state);
}
/* Activity.java */
final void attach(){
//根据窗口策略,会生成不同的窗口对象,这里默认生成的是phoneWindow,Window可以看成界面的框架抽象,有了window后,下一步要生成具体的View内容,就是Activity中的mDecor。
mWindow= new PhoneWindow(this, window);
}
生成DecorView的过程是由setContentview发起的,这也是在onCreate中调用这个函数的原因,Activity中的setContentview是一个中介,最终要有window对象完成DecorView的构造。因为不同的窗口策略,DecorView肯定是不同的。
public void setContentView(@LayoutRes intlayoutResID) {
//这里设置内容资源的ID
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
private void initWindowDecorActionBar() {
window.getDecorView();
}
/*PhoneWindow.java*/
public final View getDecorView() {
installDecor();//如果mDecor为null,就生成一个Décor对象,installDecor这个函数还有一个任务就是生成mContentParent,它是由layoutResID生成的View树的根。
mContentParent= generateLayout(mDecor);
}
protected ViewGroup generateLayout(){
//获取窗口样式
TypedArraya = getWindowStyle();
//根据样式,为LayoutResource挑选匹配的资源
if(a.getBoolean(R.styleable.Window_windowNoTitle, false)) {
requestFeature(FEATURE_NO_TITLE);
}…
//根据layoutSource指定的layout文件,来inflate出相应的view对象,把这个对象addview到mDecor中。
final View root= inflater.inflate(layoutResource, null);
addView(root,。。。);
}
Step2、/*ActivityThread.java*/
通过第一步Activity已经创建了Window和Decorview,接下来就是把它添加到本地的WindowManagerGlobal中,继而注册到WMS中。
final void handleResumeActivity(){
//这个函数会调用Activity的onResume函数
r= performResumeActivity(token, clearHide, reason);
r.window= r.activity.getWindow();//Activity对应的window对象
Viewdecor = r.window.getDecorView();//最外围的DecorView
ViewManagerwm = a.getWindowManager();//也就是Windowmanager
l.type= WindowManager.LayoutParams.TYPE_BASE_APPLICATION;//窗口类型
wm.addView(decor,l);//把Décor添加到本地的全局记录中
}
wm.addView由WindowManagerImpl.java,间接调用到WindowManagerGlobal.java中。
/*WindowManagerGlobal.java*/
public void addView(){
//查找是不是添加过这个View对象
intindex = findViewLocked(view, false);
//为这个view生成一个配套的ViewRootImpl
root= new ViewRootImpl(view.getContext(), display);
//把DecorView,viewrootimpl,params添加到三个数组中
mViews.add(view);
mRoots.add(root);
mParams.add(wparams);
//把view注册到WMS中,以上的调用都还在本地进程,这里函数是跨进程的开始。
root.setView(view,wparams, panelParentView);
}
插播几个窗口概念,因为前面wm.addView时提到了WindowmanagerImpl。
Activity跟Window的关系:Activity不直接管理ViewTree,这之间还有一个mWindow对象,就是Activity的内部变量,默认是phoneWindow;
Window和WindowManagerImpl的关系:window是面向Activity的,是UI界面的外框,框里面的东西是由具体的window子类phonewindow规划的,Window还要跟窗口管理员WMS通信,一个应用中会存在多个window,如果这些window都单独跟wms通信,就比较乱,所以这需要一个管理就是WindowManager,这个Windowmanager是一个接口类,真正的实现是WindowManagerImpl,它同时也是应用中窗口的管理者;
窗口策略代表了Android显示系统遵循的统一的窗口显示规则。默认情况生成的一个window是PhoneWindow,就是针对手机设备的,WindowmanagerPolicy是窗口管理策略的接口类,定义了一个窗口要遵循的通用规范及要提供的接口,因为系统可能同时支持多种窗口类别,所以在运行中要指定具体的窗口和管理策略,PhoneWindowmanager就是针对手机的具体的窗口管理策略类。