1 获得显示设备信息:
DisplayManagerService 启动后从SurfaceFlinger当中获取到系统默认的Display 与HDMI display的信息。
2 应用程序端指定其应用ContextImpl的Display。
3 应用程序获得Surface和配置Surface,这个surface对应于SurfaceFlinger中的Layer;
WindowManagerService作为一个系统服务,主要管理系统中所有的应用的Window。在WMS中,每个Window都有一个对应的WindowState对象。
3.1 addWindow,该函数在WindowManagerService当中,由WindowManagerImpl中的addView函数调用到,并且将Window所在的Display作为参数带到WMS当中。
关键是WindowManagerImpl的mContext,从这个mContext获取displayId
3.2在addWindow函数,WMS首先找到窗口所在的Display,创建WindowState,然后将窗口加到Display中的Windowlist当中。win.mToken.addWindow(win);
3.3 WindowState,获取对应Display的layerstack将其放置在WindowStateAnimator当中,并且将值设置到SurfaceFlinger当中与之对应的Layer中,告知SurfaceFlinger自己所在Display。mSurfaceControl.setLayerStack(mLayerStack);
4 绘制Surface
SurfaceFlinger作为Android在native层比较重要的一个系统服务,主要作用是compose所有的layer,将其绘制输出到显示设备当中,也就是物理Display当中。
SurfaceFlinger根据Layer当中的layerStack成员,获知需要将该Layer绘制到具体哪一个Display当中。
java
@frameworks/base/core/java/android/app/ActivityThread.java
ActivityThread.performLaunchActivity()
@frameworks/base/core/java/android/app/Activity.java
activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, config,r.referrer, r.voiceInteractor, window,);
mWindow = new PhoneWindow(this, window, activityConfigCallback);
@frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java
mContext = context; //PhoneWindow设置mContext为Activity里的context
mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE), mToken, (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
//context是attach传入的值,使用context创建WindowManager
if (wm == null) { //如果wm为空则创建使用mContext创建WindowManager,mContext是PhoneWindow保存的值
wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
}
mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
return new WindowManagerImpl(mContext, parentWindow, mWindowContextToken); //创建WindowManagerImpl,mContext是wm的,wm有两种情况
mContext = context;
mParentWindow = parentWindow;
1. Activity 为例来分析应用窗口的添加过程
@frameworks/base/core/java/android/app/ActivityThread.java
handleResumeActivity
@frameworks/base/core/java/android/view/WindowManagerImpl.java
View decor = r.window.getDecorView();
wm.addView(decor, l);
mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow, mContext.getUserId()); //WindowManagerImpl的mContext
2. 直接添加view
@MyApplication/app/src/main/java/com/example/myapplication/MainActivity.java
TextView textView = new TextView(this); // context传入this,this是当前的MainActivity
Log.d(TAG, "MyService onCreate: startActivityAsUser, thisContext=" + this.toString());
textView.setText("MyService");
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
layoutParams.type = WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
windowManager.addView(textView, layoutParams);
mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow, mContext.getUserId()); //WindowManagerImpl的mContext
addView流程:
@frameworks/base/core/java/android/view/WindowManagerGlobal.java
mGlobal.addView(view, params, mContext.getDisplayNoVerify(), mParentWindow, mContext.getUserId()); //void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow, int userId)
root = new ViewRootImpl(view.getContext(), display);
@frameworks/base/core/java/android/view/ViewRootImpl.java
root.setView(view, wparams, panelParentView, userId);
requestLayout();
mWindowSession.addToDisplayAsUser(mWindow, mWindowAttributes, mDisplay.getDisplayId()); // mDisplay是addView的时候传入的display