接上一篇《Activity页面加载流程(一)》
上一篇讲了Window的创建,但其显示流程还没有讲清楚就跑路了
废话不多说,我们continue
PS:英文用错了场景别笑话,谁让它是关键词字
这个单词拼不成汉语吧
WindowManager、WindowManagerImpl和WindowManagerGlobal的关系及内部机制
WindowManager是一个继承于ViewManager的接口,实现类是WindowManagerImpl
Activity.java
final void attach(...){
...
mWindow.setWindowManager(
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE), //系统的WindowManger
mToken, mComponent.flattenToString(),
(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
...
mWindowManager = mWindow.getWindowManager();
}
Window.java
public void setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) {
...
//wm的createLocalWindowManager方法又重新new了WindowManagerImpl
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
}
public WindowManager getWindowManager() {
return mWindowManager;
}
WindowManagerImpl.java
WindowManagerImpl是WindowManager的实现类,显实现了addView、updateViewLayout、removeView等方法,可是这哥们胸怀宇宙,有空还要看星星,别看它是一个实现类,名字还带一个Impl,却把具体工作都交给了单例的WindowManagerGlobal。
public final class WindowManagerImpl implements WindowManager {
//全局单例
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
...
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}
@Override
public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.updateViewLayout(view, params);
}
@Override
public void removeView(View view) {
mGlobal.removeView(view, false);
}
...
}
WindowManagerGlobal.java
WindowManagerGlobal是单例的,所以它内部用几个集合来保存Window及参数和所对应的View
//每个Window对应的View
private final ArrayList mViews = new ArrayList();
//每个Window对应的ViewRootImpl
private final ArrayList mRoots = new ArrayList();
//每个Window的参数
private final ArrayList mParams = new ArrayList();
public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) {
ViewRootImpl root;
...
//创建ViewRootImpl,View的invalidate更新view的时候,就是从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 {
//重要方法
root.setView(view, wparams, panelParentView);
}
...
}
Window的显示
WindowManagerService作为一个系统级的服务运行在一个单独的进程,所以WindowManager和它之间的交互是一个IPC(进程间通信)过程,ViewRootImpl充当了桥梁的作为
通过Binder机制获取WMS,在WindowManagerService获取Session,进而通过session的addToDisplay方法和WMS的addWindow添加到将Window添加到设备
ViewRootImpl.java
final IWindowSession mWindowSession;
public ViewRootImpl(Context context, Display display) {
...
//在构造方法里调用WindowManagerGlobal的static方法getWindowSession()初始化IWindowSession
mWindowSession = WindowManagerGlobal.getWindowSession();
...
}
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
...
//开始View的三大流程,测量、布局和绘制
requestLayout();
...
try {
...
//显示
res = mWindowSession.addToDisplay(mWindow, ...);
...
}
...
}
WindowManagerGlobal.java
public static IWindowSession getWindowSession() {
synchronized (WindowManagerGlobal.class) {
if (sWindowSession == null) {
try {
InputMethodManager imm = InputMethodManager.getInstance();
IWindowManager windowManager = getWindowManagerService();
//从WindowManagerService里获取WindowSession
sWindowSession = windowManager.openSession(
new IWindowSessionCallback.Stub() {
@Override
public void onAnimatorScaleChanged(float scale) {
ValueAnimator.setDurationScale(scale);
}
},
imm.getClient(), imm.getInputContext());ffgetWindowManagerService
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
return sWindowSession;
}
}
public static IWindowManager getWindowManagerService() {
synchronized (WindowManagerGlobal.class) {
if (sWindowManagerService == null) {
//从binder里获取WindowManagerService
sWindowManagerService = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
try {
if (sWindowManagerService != null) {
ValueAnimator.setDurationScale(sWindowManagerService.getCurrentAnimatorScale());
}
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
return sWindowManagerService;
}
}
WindowManagerService.java
@Override
public IWindowSession openSession(IWindowSessionCallback callback, IInputMethodClient client, IInputContext inputContext) {
if (client == null) throw new IllegalArgumentException("null client");
if (inputContext == null) throw new IllegalArgumentException("null inputContext");
//Session就在这里创建,Session和WindowManagerService相互持有
Session session = new Session(this, callback, client, inputContext);
return session;
}
Session.java
@Override
public int addToDisplay(IWindow window, ...) {
//这里调用WMS的addWindow方法
return mService.addWindow(this, window, ...);
}
Window已经显示了
Activity的页面加载流程已经结束,涉及到的类比较多,可能有说的不明的或错误的地方,请谅解
源码一个class动辄万行,内部类N多个
是不是脑壳疼
疼就对了
不然你以为你zou是谷歌开发工程师了
然
不进则退
学习还是必须的
没有什么比自身的强大更重要
你想要的
时间都会给你
学会自我约束
才能自我自由
鸡汤是给你们喝的,我喜欢吃肉
End