Android WindowManagerService解析(2)
来源:互联网 发布:简谱大师 mac 编辑:程序博客网 时间:2024/05/22 13:27
一、Activity背后的Window
每个Activity都对应一个Window,Activity并不是UI真实的载体,真实载体是Activity中的Window。
Activity.java
private Window mWindow;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) { // 1、创建Window mWindow = PolicyManager.makeNewWindow(this); mWindow.setCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) { mWindow.setSoftInputMode(info.softInputMode); } if (info.uiOptions != 0) { mWindow.setUiOptions(info.uiOptions); } // 2、创建WindowManager,并将其设置到Window中 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();}public Window getWindow() { return mWindow;}
在Activity实例化之后,会调用attach方法,这个方法是Activity最早的一个回调方法,可以看到在这个里面对Window进行了创建。
PolicyManager.java
public final class PolicyManager { private static final String POLICY_IMPL_CLASS_NAME = "com.android.internal.policy.impl.Policy"; private static final IPolicy sPolicy; static { Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME); sPolicy = (IPolicy)policyClass.newInstance(); } public static Window makeNewWindow(Context context) { return sPolicy.makeNewWindow(context); }}public class Policy implements IPolicy { private static final String TAG = "PhonePolicy"; public Window makeNewWindow(Context context) { return new PhoneWindow(context); }}
可以看到,创建的是一个PhoneWindow实例,Window是一个抽象类,PhoneWindow继承了Window类。
既然Window是UI的载体,那么我们通常在Activity中执行setContentView方法,莫非真实执行是在Window里面,没错,你猜对了,下面我们来看看。
public void setContentView(int layoutResID) { getWindow().setContentView(layoutResID); initActionBar();}
哈哈,看到没有,getWindow方法返回的就是前面创建的PhoneWindow对象,所以,setContentView的真正执行者其实是Window对象。
下面看看PhoneWindow的setContentView方法。
@Overridepublic void setContentView(int layoutResID) { if (mContentParent == null) { installDecor(); } else { mContentParent.removeAllViews(); } mLayoutInflater.inflate(layoutResID, mContentParent); final Callback cb = getCallback(); if (cb != null && !isDestroyed()) { cb.onContentChanged(); }}
这个其实创建一个DecorView,DecorView是一个ViewGroup,然后将我们的View添加到这个DecorView中。
二、Window的大管家WindowManager
在Window的身边,有一个得力的管家就是WindowManager,它帮助Window完成各项显示操作。WindowManager的实例化也在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) { // 1、创建Window mWindow = PolicyManager.makeNewWindow(this); mWindow.setCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) { mWindow.setSoftInputMode(info.softInputMode); } if (info.uiOptions != 0) { mWindow.setUiOptions(info.uiOptions); } // 2、创建WindowManager,并将其设置到Window中 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();}
在第二步中,我们看到通过context.getSystemService(Context.WINDOW_SERVICE)获取到WindowManager对象,然后及其设置到Window对象中,从而实现对Window的管理。
ContextImpl.java
@Overridepublic Object getSystemService(String name) { ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name); return fetcher == null ? null : fetcher.getService(this);}
从SYSTEM_SERVICE_MAP这个Map中来获取服务代理对象,并且在这之前会将各类服务注册进去。
private static void registerService(String serviceName, ServiceFetcher fetcher) { if (!(fetcher instanceof StaticServiceFetcher)) { fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++; } SYSTEM_SERVICE_MAP.put(serviceName, fetcher);}
上面是注册方法,下面具体看看WindowService的注册过程
registerService(WINDOW_SERVICE, new ServiceFetcher() { Display mDefaultDisplay; public Object getService(ContextImpl ctx) { Display display = ctx.mDisplay; if (display == null) { if (mDefaultDisplay == null) { DisplayManager dm = (DisplayManager)ctx.getOuterContext(). getSystemService(Context.DISPLAY_SERVICE); mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY); } display = mDefaultDisplay; } return new WindowManagerImpl(display);}});
可以看到,我们通过的使用getSystemService(Context.WINDOW_SERVICE)获取得到的是一个WindowManagerImpl对象,并且它并不是一个真正的WindowManagerService的远程代理对象,而是一个对DisplayManagerService远程代理对象的封装。具体可以参考文章 Android WindowManagerService解析(1)
弄清了这个WindowManager之后,我们回过头去看看Window的setWindowManager的过程。
Window.java
public void setWindowManager(WindowManager wm, IBinder appToken, String appName, boolean hardwareAccelerated) { mAppToken = appToken; mAppName = appName; mHardwareAccelerated = hardwareAccelerated || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false); if (wm == null) { wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE); } mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);}
可以看到,Window中的mWindowManager并且直接使用的前面创建一个WindowManagerImpl对象,而是通过WindowManagerImpl调用createLocalWindowManager来创建的一个WindowManagerImpl对象。
WindowManagerImpl
public final class WindowManagerImpl implements WindowManager { public WindowManagerImpl createLocalWindowManager(Window parentWindow) { return new WindowManagerImpl(mDisplay, parentWindow); }}
可以看到,它就是重新创建了一个WindowManagerImpl对象。从这里我们可以知道,在Window中的WindowManager管家是一个WindowManagerImpl对象。
三、UI的显示过程
Window仅仅只是一个载体,真正的显示是由WindowManager来处理的。
下面来看看ActivityThread的handleResumeActivity方法。
ActivityThread.java
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) { ActivityClientRecord r = performResumeActivity(token, clearHide); if (r != null) { // 1、获取Activity对象 final Activity a = r.activity; // 2、得到Activity的Window对象 r.window = r.activity.getWindow(); // 3、拿到Window中的decorView对象 View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); // 4、拿到WindowManager对象 ViewManager wm = a.getWindowManager(); // 5、得到WindowManger的布局属性 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; // 6、调用WindowManager的addView方法 wm.addView(decor, l); } }
看到这里是不是很熟悉,我们平时在使用WindowManager的时候也是这样使用的,这里我们就突然明白原来Activity内部就是封装了一个windowManager,真正使用的还是它的addView方法,这个我们在使用WindowManager经常使用。
- Android WindowManagerService解析(2)
- Android WindowManagerService解析(1)
- Android WindowManagerService解析(3)
- Android WindowManagerService解析(4)
- Android WindowManagerService解析(5)
- Android WindowManagerService解析(6)
- Android解析WindowManagerService(一)WMS的诞生
- Android WindowManagerService
- Android WindowManagerService
- Android解析WindowManagerService(二)WMS的重要成员和Window的添加过程
- Android窗口管理分析(2):WindowManagerService窗口管理之Window添加流程
- android WindowManagerService addFakeWindow 研究
- Android按键消息传播流程(WindowManagerService.java)
- Android按键消息传播流程(WindowManagerService.java)
- Android WindowManagerService机制分析(一):窗口的显示层级
- WindowManagerService
- Android WindowManagerService相关的Session
- Android应用程序窗口(Activity)与WindowManagerService服务的连接过程分析
- 形态学处理
- ubuntu下双环境
- 使用Fiddler调试线上JS代码
- canvas绘图基础(一)
- SSR 一键安装包
- Android WindowManagerService解析(2)
- 数据并发性和一致性介绍--Data Concurrency and Consistency
- Matlab安装时遇到software caused connection abort recv failed 问题
- PAT
- JS小知识
- 关系型数据库工作原理-客户端连接管理器(翻译自Coding-Geek文章)
- QT_SVG格式图片浏览器
- ECharts(中国地图篇)的使用
- POJ