- 浏览: 23744 次
- 性别:
- 来自: 北京
最新评论
page5
在这篇文章中, 我们分析一下ContextImpl的getSystemService函数,
1 public Object getSystemService(String name) {
2 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
3 return fetcher == null ? null : fetcher.getService(this);
4 }
第2行(ContextImpl->getSystemService)SYSTEM_SERVICE_MAP的定义如下:
private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP = new HashMap<String, ServiceFetcher>();
在ContextImpl加载过程中, 会初始化SYSTEM_SERVICE_MAP, 我们这里只关心LAYOUT_INFLATER_SERVICE服务, 相关代码如下:
static {
............
registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
}});
............
}
ContextImpl类的registerService函数的定义如下:
1 private static int sNextPerContextServiceCacheIndex = 0;
2 private static void registerService(String serviceName, ServiceFetcher fetcher) {
3 if (!(fetcher instanceof StaticServiceFetcher)) {
4 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
5 }
6 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
7 }
registerService函数很好理解吧.
我们回到getSystemService的第3行(ContextImpl->getSystemService), 这里会调用ServiceFetcher的getService函数, ServiceFetcher是ContextImpl的一个内部类, ServiceFetcher的getService函数定义如下:
1 public Object getService(ContextImpl ctx) {
2 ArrayList<Object> cache = ctx.mServiceCache;
3 Object service;
4 synchronized (cache) {
5 if (cache.size() == 0) {
6 // Initialize the cache vector on first access.
7 // At this point sNextPerContextServiceCacheIndex
8 // is the number of potential services that are
9 // cached per-Context.
10 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
11 cache.add(null);
12 }
13 } else {
14 service = cache.get(mContextCacheIndex);
15 if (service != null) {
16 return service;
17 }
18 }
19 service = createService(ctx);
20 cache.set(mContextCacheIndex, service);
21 return service;
22 }
23 }
第5-18行(ServiceFetcher->getService)会尝试在cache里取.
第19行(ServiceFetcher->getService)会调用createService函数, 来创建一个Service.
其实这里调用的是这句
return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
我靠, 来看一看PolicyManager的makeNewLayoutInflater函数的实现吧:
public static LayoutInflater makeNewLayoutInflater(Context context) {
return sPolicy.makeNewLayoutInflater(context);
}
还记得这逻辑么?这会导致com.android.internal.policy.impl.Policy的makeNewLayoutInflater函数的调用, 定义如下:
public LayoutInflater makeNewLayoutInflater(Context context) {
return new PhoneLayoutInflater(context);
}
FUCK, 绕了这么大一圈, 最后还是会new一个PhoneLayoutInflater对象, 因此, 我们就知道了Window所拥有的其实是个PhoneLayoutInflater对象.
第20行(ServiceFetcher->getService)会将刚创建的Service设置到cache中去.
page6
在这篇文章里, 我们分析一下Window的setWindowManager函数的实现, 在这个函数里会为该Window创建一个WindowManager.
Window的setWindowManager函数的定义如下:
1 public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
2 boolean hardwareAccelerated) {
3 mAppToken = appToken;
4 mAppName = appName;
5 mHardwareAccelerated = hardwareAccelerated
6 || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
7 if (wm == null) {
8 wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
9 }
10 mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
11 }
第3行(Window->setWindowManager)会保存activity的token
第4行(Window->setWindowManager)会保存appName
第5-6行(Window->setWindowManager)判断是否需要硬件加速, 判断是否的条件是否用户显示启动该选项或者系统支持
第7-9行(Window->setWindowManager)会通过mContext来获得WINDOW_SERVICE服务, 详细分析可以参考page7文件.
第10行(Window->setWindowManager)会调用WindowManagerImpl的createLocalWindowManager函数来得到一个WindowManagerImpl对象, 并用该对象初始化成员变量mWindowManager.createLocalWindowManager函数的定义如下:
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mDisplay, parentWindow);
}
createLocalWindowManager函数只不过又创建了一个WindowManagerImpl对象, 只不过该对象有parentWindow而已.
page7
这里我们分析一下ContextImpl的WINDOW_SERVICE服务的获取过程, 而这是通过调用getSystemService函数来得到的,
getSystemService函数的实现逻辑其实我们已经分析过了, 其实最后会执行到这里:
1 registerService(WINDOW_SERVICE, new ServiceFetcher() {
2 public Object getService(ContextImpl ctx) {
3 Display display = ctx.mDisplay;
4 if (display == null) {
5 DisplayManager dm = (DisplayManager)ctx.getOuterContext().getSystemService(
6 Context.DISPLAY_SERVICE);
7 display = dm.getDisplay(Display.DEFAULT_DISPLAY);
8 }
9 return new WindowManagerImpl(display);
10 }});
是不是很熟悉.
第5-6行(ContextImpl->registerService)又通过调用getSystemService函数来获得DISPLAY_SERVICE服务, 别说了, 看下面的代码:
registerService(DISPLAY_SERVICE, new ServiceFetcher() {
@Override
public Object createService(ContextImpl ctx) {
return new DisplayManager(ctx.getOuterContext());
}});
会new一个DisplayManager, 关于DisplayManager的构造过程可以参考page8文件.
第7行(ContextImpl->registerService)会调用DisplayManager的getDisplay函数, 关于getDisplay函数的详细分析可以参考page9文件.
第9行(ContextImpl->registerService)会用刚刚得到的Display对象new一个WindowManagerImpl, 并返回. WindowManagerImpl函数的构造函数如下所示:
public WindowManagerImpl(Display display) {
this(display, null);
}
private WindowManagerImpl(Display display, Window parentWindow) {
mDisplay = display;
mParentWindow = parentWindow;
}
page8
这里我们看一下DisplayManager的构造过程, DisplayManager的构造函数如下:
1 public DisplayManager(Context context) {
2 mContext = context;
3 mGlobal = DisplayManagerGlobal.getInstance();
4 }
第2行(DisplayManager->DisplayManager)会保存Context
第3行(DisplayManager->DisplayManager)会调用DisplayManagerGlobal.getInstance()函数来获得DisplayManagerGlobal实例, DisplayManagerGlobal的getInstance函数的定义如下:
1 public static DisplayManagerGlobal getInstance() {
2 synchronized (DisplayManagerGlobal.class) {
3 if (sInstance == null) {
4 IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
5 if (b != null) {
6 sInstance = new DisplayManagerGlobal(IDisplayManager.Stub.asInterface(b));
7 }
8 }
9 return sInstance;
10 }
11 }
从getInstance函数的定义可以知道, getInstance主要逻辑就是通过ServiceManager得到DISPLAY_SERVICE服务, 这是Binder相关的. 获得DISPLAY_SERVICE服务之后会用这个服务来创建一个DisplayManagerGlobal对象,
DisplayManagerGlobal的构造函数的定义如下:
private DisplayManagerGlobal(IDisplayManager dm) {
mDm = dm;
}
在这篇文章中, 我们分析一下ContextImpl的getSystemService函数,
1 public Object getSystemService(String name) {
2 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
3 return fetcher == null ? null : fetcher.getService(this);
4 }
第2行(ContextImpl->getSystemService)SYSTEM_SERVICE_MAP的定义如下:
private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP = new HashMap<String, ServiceFetcher>();
在ContextImpl加载过程中, 会初始化SYSTEM_SERVICE_MAP, 我们这里只关心LAYOUT_INFLATER_SERVICE服务, 相关代码如下:
static {
............
registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
}});
............
}
ContextImpl类的registerService函数的定义如下:
1 private static int sNextPerContextServiceCacheIndex = 0;
2 private static void registerService(String serviceName, ServiceFetcher fetcher) {
3 if (!(fetcher instanceof StaticServiceFetcher)) {
4 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
5 }
6 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
7 }
registerService函数很好理解吧.
我们回到getSystemService的第3行(ContextImpl->getSystemService), 这里会调用ServiceFetcher的getService函数, ServiceFetcher是ContextImpl的一个内部类, ServiceFetcher的getService函数定义如下:
1 public Object getService(ContextImpl ctx) {
2 ArrayList<Object> cache = ctx.mServiceCache;
3 Object service;
4 synchronized (cache) {
5 if (cache.size() == 0) {
6 // Initialize the cache vector on first access.
7 // At this point sNextPerContextServiceCacheIndex
8 // is the number of potential services that are
9 // cached per-Context.
10 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
11 cache.add(null);
12 }
13 } else {
14 service = cache.get(mContextCacheIndex);
15 if (service != null) {
16 return service;
17 }
18 }
19 service = createService(ctx);
20 cache.set(mContextCacheIndex, service);
21 return service;
22 }
23 }
第5-18行(ServiceFetcher->getService)会尝试在cache里取.
第19行(ServiceFetcher->getService)会调用createService函数, 来创建一个Service.
其实这里调用的是这句
return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
我靠, 来看一看PolicyManager的makeNewLayoutInflater函数的实现吧:
public static LayoutInflater makeNewLayoutInflater(Context context) {
return sPolicy.makeNewLayoutInflater(context);
}
还记得这逻辑么?这会导致com.android.internal.policy.impl.Policy的makeNewLayoutInflater函数的调用, 定义如下:
public LayoutInflater makeNewLayoutInflater(Context context) {
return new PhoneLayoutInflater(context);
}
FUCK, 绕了这么大一圈, 最后还是会new一个PhoneLayoutInflater对象, 因此, 我们就知道了Window所拥有的其实是个PhoneLayoutInflater对象.
第20行(ServiceFetcher->getService)会将刚创建的Service设置到cache中去.
page6
在这篇文章里, 我们分析一下Window的setWindowManager函数的实现, 在这个函数里会为该Window创建一个WindowManager.
Window的setWindowManager函数的定义如下:
1 public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
2 boolean hardwareAccelerated) {
3 mAppToken = appToken;
4 mAppName = appName;
5 mHardwareAccelerated = hardwareAccelerated
6 || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
7 if (wm == null) {
8 wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
9 }
10 mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
11 }
第3行(Window->setWindowManager)会保存activity的token
第4行(Window->setWindowManager)会保存appName
第5-6行(Window->setWindowManager)判断是否需要硬件加速, 判断是否的条件是否用户显示启动该选项或者系统支持
第7-9行(Window->setWindowManager)会通过mContext来获得WINDOW_SERVICE服务, 详细分析可以参考page7文件.
第10行(Window->setWindowManager)会调用WindowManagerImpl的createLocalWindowManager函数来得到一个WindowManagerImpl对象, 并用该对象初始化成员变量mWindowManager.createLocalWindowManager函数的定义如下:
public WindowManagerImpl createLocalWindowManager(Window parentWindow) {
return new WindowManagerImpl(mDisplay, parentWindow);
}
createLocalWindowManager函数只不过又创建了一个WindowManagerImpl对象, 只不过该对象有parentWindow而已.
page7
这里我们分析一下ContextImpl的WINDOW_SERVICE服务的获取过程, 而这是通过调用getSystemService函数来得到的,
getSystemService函数的实现逻辑其实我们已经分析过了, 其实最后会执行到这里:
1 registerService(WINDOW_SERVICE, new ServiceFetcher() {
2 public Object getService(ContextImpl ctx) {
3 Display display = ctx.mDisplay;
4 if (display == null) {
5 DisplayManager dm = (DisplayManager)ctx.getOuterContext().getSystemService(
6 Context.DISPLAY_SERVICE);
7 display = dm.getDisplay(Display.DEFAULT_DISPLAY);
8 }
9 return new WindowManagerImpl(display);
10 }});
是不是很熟悉.
第5-6行(ContextImpl->registerService)又通过调用getSystemService函数来获得DISPLAY_SERVICE服务, 别说了, 看下面的代码:
registerService(DISPLAY_SERVICE, new ServiceFetcher() {
@Override
public Object createService(ContextImpl ctx) {
return new DisplayManager(ctx.getOuterContext());
}});
会new一个DisplayManager, 关于DisplayManager的构造过程可以参考page8文件.
第7行(ContextImpl->registerService)会调用DisplayManager的getDisplay函数, 关于getDisplay函数的详细分析可以参考page9文件.
第9行(ContextImpl->registerService)会用刚刚得到的Display对象new一个WindowManagerImpl, 并返回. WindowManagerImpl函数的构造函数如下所示:
public WindowManagerImpl(Display display) {
this(display, null);
}
private WindowManagerImpl(Display display, Window parentWindow) {
mDisplay = display;
mParentWindow = parentWindow;
}
page8
这里我们看一下DisplayManager的构造过程, DisplayManager的构造函数如下:
1 public DisplayManager(Context context) {
2 mContext = context;
3 mGlobal = DisplayManagerGlobal.getInstance();
4 }
第2行(DisplayManager->DisplayManager)会保存Context
第3行(DisplayManager->DisplayManager)会调用DisplayManagerGlobal.getInstance()函数来获得DisplayManagerGlobal实例, DisplayManagerGlobal的getInstance函数的定义如下:
1 public static DisplayManagerGlobal getInstance() {
2 synchronized (DisplayManagerGlobal.class) {
3 if (sInstance == null) {
4 IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
5 if (b != null) {
6 sInstance = new DisplayManagerGlobal(IDisplayManager.Stub.asInterface(b));
7 }
8 }
9 return sInstance;
10 }
11 }
从getInstance函数的定义可以知道, getInstance主要逻辑就是通过ServiceManager得到DISPLAY_SERVICE服务, 这是Binder相关的. 获得DISPLAY_SERVICE服务之后会用这个服务来创建一个DisplayManagerGlobal对象,
DisplayManagerGlobal的构造函数的定义如下:
private DisplayManagerGlobal(IDisplayManager dm) {
mDm = dm;
}
发表评论
-
Activity与WindowManagerService连接的过程(三)
2018-04-16 16:27 620page11 WindowManagerService ... -
Activity与WindowManagerService连接的过程(二)
2018-04-16 16:36 762page6 WindowManagerGlobal的getW ... -
Activity与WindowManagerService连接的过程(一)
2018-04-16 16:21 983page1 Activity组件在 ... -
Activity的ViewRoot的创建过程(三)
2017-11-06 14:25 737page7 在这篇文章里, 我们分析一下W类的构造过程. W ... -
Activity的ViewRoot的创建过程(二)
2017-11-06 14:29 935page4 我们看一下ViewRootImpl对象的创 ... -
Activity的ViewRoot的创建过程(一)
2017-11-06 14:27 1077page1 当一个Activity第一次激活的时候会为该Ac ... -
Activity的Window和WindowManager的创建过程(三)
2017-07-05 11:49 1332page9 在这里我们分析一下DisplayManager的 ... -
Activity的Window和WindowManager的创建过程(一)
2017-07-05 11:27 604page1 我们开始分析一下Activity的Window和 ... -
Acitivy创建Context的过程(二)
2017-06-21 14:11 511page4 在这里我们分析一下ContextImpl的ini ... -
Acitivy创建Context的过程(一)
2017-06-21 14:15 634page1 从本篇文章开始,我们分析一下Activity创建 ... -
应用程序进程与SurfaceFlinger的连接过程
2017-06-21 11:49 1056我们从SurfaceComposerClient对象的创建开始 ... -
Android源码之SurfaceFlinger的启动(三)
2017-04-20 11:09 1041page11 我们来看一下SurfaceFlinger ... -
Android源码之SurfaceFlinger的启动(二)
2017-04-18 15:15 868page6 我们看一下Thread的run函数的实现: ... -
Android源码之SurfaceFlinger的启动(一)
2017-04-17 10:07 992page1 在Android系统中, 显示系统在底层是通过S ... -
Android源码之Zygote
2015-12-15 11:45 515当ActivityManagerService启动一个应用程序 ... -
Android源码之Binder(五)
2015-12-04 09:19 1507Service组件在启动时,需要将自己注册到Service M ... -
Android源码之Binder(四)
2015-12-04 09:18 1921case BINDER_SET_MAX_THREADS: ... -
Android源码之Binder(三)
2015-12-04 09:17 908{ int ret; struct binder_pr ... -
Android源码之Binder(二)
2015-12-04 09:15 546分析完Binder驱动程序的打开和内存分配的过程之后,我们看一 ... -
Android源码之Binder(一)
2015-12-04 09:12 993在Android系统中,进程间通信使用的是Binder机制。B ...
相关推荐
Window是一个抽象类,具体实现是 PhoneWindow 。不管是 Activity 、 Dialog 、 Toast 它们的视图都是附加在Window上的,因此Window实际上是View的直接管理者。
我们先来深入理解Window和WindowManager的相关知识点。 1. **WindowManager接口与实现**: Android提供了`WindowManager`接口,用于操作窗口。然而,真正实现`WindowManager`功能的是`WindowManagerGlobal`类,它...
Window和WindowManager之间的协作过程大致如下: 1. 当一个Activity启动时,系统会为该Activity创建一个默认的Window。这个Window通常是一个PhoneWindow,包含了DecorView,它是根ViewGroup,用于承载应用的布局。 ...
创建一个Window,需要通过WindowManager即可完成,WindowManager是外界访问Window的入口,Window具体实现位于WindowManagerService中,WindowManager和WindowManagerService的交互是一个IPC的过程。Android中,所有...
1. **获取WindowManager实例**:通过Activity的`getWindowManager()`方法或者Context的`getSystemService(Context.WINDOW_SERVICE)`来获取WindowManager实例。 2. **定义布局文件**:创建XML布局文件,包含弹窗所需...
- 使用`WindowManager`服务,通常在`Service`或`Activity`中初始化`WindowManager`实例:`WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);` - 创建一个`LayoutParam`对象,定义...
Android悬浮窗实现原理和WindowManager详解 Android悬浮窗是指在Android系统中,可以悬浮在屏幕上的一种窗口,常见于QQ视频、手机杀毒软件的桌面小助手等应用中。要实现悬浮窗,需要使用WindowManager来管理窗口。...
Activity启动流程是Android系统中一个非常核心的部分,它是应用程序组件之一,负责创建和管理应用的用户界面。当我们想要启动一个新的Activity时,背后有一系列复杂的交互过程,涉及多个组件和类。本文将通过代码...
在Android系统中,WindowManager服务负责管理所有应用的窗口,而Activity实际上就是一种特殊的Window。默认情况下,Activity会全屏显示,但我们可以通过修改Activity的属性和使用自定义布局来改变这一行为。 1. ...
`attach`函数使得Activity能够访问到系统的各种服务,如`WINDOW_SERVICE`,从而能够创建和管理窗口。 在当前Activity中,`PhoneWindow`被实例化,它是Activity的窗口实现。`PhoneWindow`设置回调,然后通过`...
首先,我们需要创建一个悬浮窗口(Floating Window),这是`WindowManager`的主要用途之一。悬浮窗口可以覆盖在其他应用之上,我们可以通过监听悬浮窗口的触摸事件来捕获Home键的按下情况。 1. **添加权限**:在...
最近有学生做毕业设计,想使用悬浮窗这种效果,其实很简单,我们可以通过系统服务WindowManager来实现此功能,本章我们来试验一下在当前Activity之上创建一个悬浮的view。 第一步:认识WindowManager 这个接口用于与 ...
本篇将深入探讨如何利用`WindowManager`来创建一个悬浮窗(Floating Window)的demo。 首先,悬浮窗的本质是在应用程序的主窗口之上添加一个额外的窗口。这种窗口通常具有较低的层级,以便它始终位于其他应用窗口之...
本教程将深入讲解如何使用`WindowManager`服务来创建和管理Android悬浮窗,并通过一个简单的Demo——WindowManagerDemo来展示其实现过程。 首先,我们要理解`WindowManager`是Android系统提供的一个接口,它允许...
在Android开发过程中,`WindowManager.LayoutParams`是一个非常重要的类,它用于配置窗口的各种属性,如位置、大小、类型等。通过本文档,我们将深入探讨`WindowManager.LayoutParams`的所有参数及其详细信息。 ###...
本文将深入探讨如何利用`WindowManager`服务和布局参数来创建这样的悬浮视频播放窗口。 首先,`WindowManager`是Android系统提供的一个接口,它允许我们添加、移除或更新视图到系统的窗口管理器中。`addView()`方法...
在Android中实现悬浮Activity,首先需要创建一个新的Activity,并在布局文件中设置其样式为Dialog样式。这可以通过修改`<style>`标签中的`parent`属性为`Theme.AppCompat.Dialog`来实现。同时,为了使Activity浮现在...
总结,创建一个`WindowManager`实现的悬浮窗口,关键在于设置正确的`LayoutParams`,包括类型、标志和初始位置。同时,通过监听触摸事件,可以实现窗口的自由移动。这个示例中的`FloatViewDemo`应该包含上述代码的...
- **PhoneWindow**: 创建PhoneWindow的过程实际上就是在Activity内部创建一个`PhoneWindow`实例。这个过程会涉及到一些窗口的初始化工作,比如设置布局和添加装饰视图。 #### setContentView `setContentView`是...