深入理解WMS(一):Window的创建过程

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) { . . . }

try {

. . .

if (activity != null) {

Context appContext = createBaseContextForActivity(r, activity);

CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());

Configuration config = new Configuration(mCompatConfiguration);

if (DEBUG_CONFIGURATION) Slog.v(TAG, ". . . ");

// 调用其 attach 方法为其关联运行过程中所依赖的一系列上下文环境变量

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);

. . .

}

} catch (Exception e) { . . . }

return activity;

}

Activityattach()方法里,系统会创建Activity所属的Window对象并为其设置回调接口,Window对象的创建是通过PolicyManagermakeNewWindow方法实现的。由于Activity实现了WindowCallback接口,因此当Window接收到外界的状态改变时就会回调Activity的方法。Callback接口中的方法很多,但是有几个却是我们都非常熟悉的,比如onAttachedToWindowonDetachedFromWindowdiapatchTouchEvent,等等

// 创建 Window 对象

mWindow = PolicyManager.makeNewWindow(this);

// 实现 Window 的 Callback 接口

mWindow.setCallback(this);

mWindow.setOnWindowDismissedCallback(this);

. . .

从上面的分析可以看出,ActivityWindow是通过PolicyManager的一个工厂方法来创建的,但是从PolicyManager的类名可以看出,它不是一个普通的类,它是一个策略类。PolicyManager中实现的几个工厂方法全部在策略接口IPolicy中声明了。

public interface IPolicy {

public Window makeNewWindow(Context context);

public LayoutInflater makeNewLayoutInflater(Context context);

public WindowManagerPolicy makeNewWindowManager();

public FallbackEventHandler makeNewFallbackEventHandler(Context context);

}

在实际的调用中,PolicyManager的真正实现是Policy类,Policy类中的makeNewWindow方法的实现如下,由此可以发现,Window的具体实现的确是PhoneWindow

public static Window makeNewWindow(Context context) {

return new PhoneWindow(context);

}

关于策略类PolicyManager是如何关联到Policy上面的,这个无法从源码中的调用关系来得出,这里猜测可能是有编译环节动态控制的。到这里Window已经创建完成了,下面分析Activity的视图是怎么附属在Window上的。由于Activity的视图由setContentView方法提供,我们只需要看setContentView方法的实现即可:

public void setContentView(int layoutResID) {

getWindow().setContentView(layoutResID);

initWindowDecorActionBar();

}

ActivitysetContentView的实现可以看出,Activity将具体实现交给了Window处理,而Window的具体实现是PhoneWindow,所以只需要看PhoneWindow的相关逻辑即可。

PhoneWindowsetContentView方法大致遵循如下几个步骤:

1. 如果没有DecorView,那么就创建它

DecorView是一个FrameLayoutDecorViewActivity中的顶级View,一般来说,它的内部包含标题栏和内部栏,但是这个会随着主题的变换而发生改变。不管怎么样,内容栏是一定要存在的,并且内容栏具体固定的id,那就是content,它的完整idandroid.R.id.contentDecorView的创建过程由installDecor方法来完成,在方法内部会通过generateDecor方法来直接创建DecorView,这个时候DecorView还只是一个空白的FrameLayout

protected DecorView generateDecor(){

return new DecorView(getContext(),-1);

}

为了初始化DecorView的结构,PhoneWindow还需要通过generateLayout方法来加载具体的布局文件到DecorView中,具体的布局文件和系统版本以及主题有关。

View in = mLayoutInflater.inflate(layoutResource, null);

最后

在此为大家准备了四节优质的Android高级进阶视频:

架构师项目实战——全球首批Android开发者对Android架构的见解

附相关架构及资料

image.png

往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术,群内还有技术大牛一起讨论交流解决问题。*
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值