android windowmanager 分析,android解析windowmanager 01:windowmanager体系

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

Window,一个抽象类,其具体的实现是PhoneWindow,它对View进行管理。WindowManager是一个接口类,继承自接口ViewManager,用来管理Window,其实现类是WindowManagerImpl。如果要对Window进行添加和删除就可以使用WindowManager,具体的工作会由WMS来完成,WindowManager和WMS通过Binder进行跨进程通信,WMS作为系统服务,有很多API是不会暴露给WindowManager的,这点与AMS和ActivityManager类似。

这里主要介绍Window管理和输入系统。

3bebbdaf49ea7c60b3f3a4493f2982ae.png

Window包含了View,并对View进行管理,Window是一个抽象的概念,并不是真实存在的,Window的实体就是View。WindowManager用来管理Window,而WindowManager所提供的功能最终会由WMS进行处理。

2. WindowManager体系

WindowManager是一个接口,继承ViewManager,ViewManager中定义了三个方法,分别用来添加、更新和删除View:frameworks/base/core/java/android/view/ViewManager.java1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18* of this class, call {@link android.content.Context#getSystemService(java.lang.String) Context.getSystemService()}.

*/

public interface{

/**

* Assign the passed LayoutParams to the passed View and add the view to the window.

*

Throws {@link android.view.WindowManager.BadTokenException} for certain programming

* errors, such as adding a second view to a window without removing the first view.

*

Throws {@link android.view.WindowManager.InvalidDisplayException} if the window is on a

* secondary {@link Display} and the specified display can't be found

* (see {@link android.app.Presentation}).

* @param view The view to be added to this window.

* @param params The LayoutParams to assign to view.

*/

public void addView(View view, ViewGroup.LayoutParams params);

public void updateViewLayout(View view, ViewGroup.LayoutParams params);

public void removeView(View view);

}

WindowManager也继承了这些方法。可以看到里面传入的参数都是View,说明WindowManager具体管理的是以View形式存在的Window。WindowManager在继承ViewManager的同时,加入了其他功能,包括Window的类型和层级相关的常量、内部类以及一些方法,其中有两个方法是根据Window的特性加入的,如下。1

2public Display getDefaultDisplay();

public void removeViewImmediate(View view);getDefaultDisplay():获取WindowManager实例将Window添加到哪个屏幕上,即得到WindowManager所管理的屏幕(Display)。

removeViewImmediate():规定在这个方法返回前要立即执行View.onDetachedFromWindow(),来完成传入的View相关的销毁工作。

Window是一个抽象类,其具体实现是PhoneWindow。在Activity启动过程中会调用ActivityThread的performLaunchActivity(),performLaunchActivity()中又会调用Activity的attach():frameworks/base/core/java/android/app/Activity.java1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22final 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, String referrer, IVoiceInteractor voiceInteractor,

Window window, ActivityConfigCallback activityConfigCallback){

attachBaseContext(context);

mFragments.attachHost(null /*parent*/);

mWindow = new PhoneWindow(this, window, activityConfigCallback); // 1

......

// 2

mWindow.setWindowManager(

(WindowManager)context.getSystemService(Context.WINDOW_SERVICE),

mToken, mComponent.flattenToString(),

(info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);

......

}

注释1,创建PhoneWindow;注释2,调用PhoneWindow的setWindowManager(),它的具体实现在PhoneWindow的父类Window中。frameworks/base/core/java/android/view/Window.java1

2

3

4

5

6

7

8

9public 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); // 1

}

mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this); // 2

}

如果传入的WindowManager为空,就会在注释1调用context的getSystemService()并传入服务的名称Context.WINDOW_SERVER,具体的实现在ContextImpl中,如下。frameworks/base/core/java/android/app/ContextImpl.java1

2

3

4

5

6

7

8

9public Object getSystemService(String name){

return SystemServiceRegistry.getSystemService(this, name);

}

public String getSystemServiceName(Class> serviceClass){

return SystemServiceRegistry.getSystemServiceName(serviceClass);

}

最终会调用SystemServiceRegistry的getSystemSeviceName()。frameworks/base/core/java/android/app/SystemServiceRegistry.java1

2

3public static String getSystemServiceName(Class> serviceClass){

return SYSTEM_SERVICE_NAMES.get(serviceClass);

}

SYSTEM_SERVICE_NAMES是一个HashMap,用来存储服务的名称。传入Context.WINDOW_SERVER对应的是什么呢?frameworks/base/core/java/android/app/SystemServiceRegistry.java1

2

3

4

5

6

7

8

9

10

11

12

13final class SystemServiceRegistry{

......

private SystemServiceRegistry(){ }

static {

......

registerService(Context.WINDOW_SERVICE, WindowManager.class, new CachedServiceFetcher() {

public WindowManager createService(ContextImpl ctx){

return new WindowManagerImpl(ctx);

}});

......

}

}

在SystemServiceRegistry的静态代码块中会调用多个registerService()方法,这里只看Context.WINDOW_SERVICE。registerService()会将传入的服务的名称存入到SYSTEM_SERVICE_NAMES中。从上面的代码可以看出,传入的Context.WINDOW_SERVICE对应的就是WindowManagerImpl的实例,因此Context的getSystemService()得到的是WindowManagerImpl实例。再回到Window的setWindowManager()中,得到WindowManagerImpl实例后转为WindowManger类型,在注释2处调用WindowManagerImpl的createLocalWindowManager():frameworks/base/core/java/android/view/WindowManagerImpl1

2

3public WindowManagerImpl createLocalWindowManager(Window parentWindow){

return new WindowManagerImpl(mContext, parentWindow);

}

在里面也创建了WindowManagerImpl,不过在创建的同时,将创建它的Window作为参数传了进来,这样WindowManagerImpl就持有Window的引用了,就可以对Window进行操作,比如,在Window中添加View,来看看WindowManagerImpl的addView():frameworks/base/core/java/android/view/WindowManagerImpl1

2

3

4

5public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params){

applyDefaultToken(params);

mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow); // 1

}

注释1,调用了WindowManagerGlobal的addView()方法,其中最后一个参数mParentWindow就是Window,WindowManagerImpl虽然是WindowManager的实现类,但是没有实现任何功能,而是将功能的实现委托给了WindowManagerGlobal,这是桥接模式。

再来看看WindowManagerImpl中是如何定义WindowManagerGlobal的:frameworks/base/core/java/android/view/WindowManagerImpl1

2

3

4

5

6

7

8

9

10

11public final class WindowManagerImpl implements WindowManager{

private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();

private final Context mContext;

private final Window mParentWindow; // 1

......

private WindowManagerImpl(Context context, Window parentWindow){

mContext = context;

mParentWindow = parentWindow;

}

......

}

WindowManagerGlobal是一个单例,说明在一个进程中只有一个WindowManagerGlobal实例。注释1,说明一个WindowManagerImpl可能会实现多个Window,即一个进程中可能会有多个WindowManagerImpl实例。

Window和WindowManager关系图:

69aef399356c94de6b8063bd29cc8713.png

PhoneWindow继承自Window,Window通过setWindowManager()方法与WindowManager发生联系。WindowManager继承自接口ViewManager,WindowManagerImpl是WindowManager接口的实现类,但是具体的功能都会委托给WindowManagerGlobal来实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值