- 浏览: 23745 次
- 性别:
- 来自: 北京
最新评论
page1
我们开始分析一下Activity的Window和WindowManager的创建过程, 在Activity的attach函数中, 不仅会创建Context, 还会创建Window和WindowsManager对象.因此我们就从Activity的attach函数开始分析:
1 final void attach(Context context, ActivityThread aThread,
2 Instrumentation instr, IBinder token, int ident,
3 Application application, Intent intent, ActivityInfo info,
4 CharSequence title, Activity parent, String id,
5 NonConfigurationInstances lastNonConfigurationInstances,
6 Configuration config) {
7 attachBaseContext(context);
8
9 mFragments.attachActivity(this, mContainer, null);
10
11 mWindow = PolicyManager.makeNewWindow(this);
12 mWindow.setCallback(this);
13 mWindow.getLayoutInflater().setPrivateFactory(this);
14 if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
15 mWindow.setSoftInputMode(info.softInputMode);
16 }
17 if (info.uiOptions != 0) {
18 mWindow.setUiOptions(info.uiOptions);
19 }
20 mUiThread = Thread.currentThread();
21
22 mMainThread = aThread;
23 mInstrumentation = instr;
24 mToken = token;
25 mIdent = ident;
26 mApplication = application;
27 mIntent = intent;
28 mComponent = intent.getComponent();
29 mActivityInfo = info;
30 mTitle = title;
31 mParent = parent;
32 mEmbeddedID = id;
33 mLastNonConfigurationInstances = lastNonConfigurationInstances;
34
35 mWindow.setWindowManager(
36 (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
37 mToken, mComponent.flattenToString(),
38 (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
39 if (mParent != null) {
40 mWindow.setContainer(mParent.getWindow());
41 }
42 mWindowManager = mWindow.getWindowManager();
43 mCurrentConfig = config;
44 }
第11行(Activity->attach)会调用PolicyManager的makeNewWindow函数来为这个Activity创建一个Window, 关于PolicyManager的makeNewWindow函数的详细分析可以参考page2文件.
private Window mWindow;
第12行(Activity->attach)会将mWindow的callback设置成当前activity, 这样mWindow就能将一些事件交给acticity去执行
第13-19行(Activity->attach)会设置Window的一些属性, 我们先不关心.
第35-38行(Activity->attach)会调用Window的setWindowManager函数, setWindowManager函数详细分析可以参考page6文件.
第39-41行(Activity->attach)会判断该Activity的mParent是否不为空, 如果不为空则会为Window的setContainer来设置成mParent的Window. 关于setContainer函数的详细分析可以参考page11文件.
第42行(Activity->attach)会调用Window的getWindowManager来得到WindowManager, 这样每一个Activity实例都会拿着一个WindowManager对象了.
page2
PolicyManager的makeNewWindow函数的定义如下:
public static Window makeNewWindow(Context context) {
return sPolicy.makeNewWindow(context);
}
PolicyManager的makeNewWindow函数只是简单地调用静态成员变量sPolicy的makeNewWindow函数, sPolicy的定义和初始化如下:
private static final String POLICY_IMPL_CLASS_NAME =
"com.android.internal.policy.impl.Policy";
private static final IPolicy sPolicy;
static {
// Pull in the actual implementation of the policy at run-time
try {
Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME);
sPolicy = (IPolicy)policyClass.newInstance();
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
POLICY_IMPL_CLASS_NAME + " could not be loaded", ex);
} catch (InstantiationException ex) {
throw new RuntimeException(
POLICY_IMPL_CLASS_NAME + " could not be instantiated", ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException(
POLICY_IMPL_CLASS_NAME + " could not be instantiated", ex);
}
}
可以看到sPolicy其实是加载的com.android.internal.policy.impl.Policy类, 为什么要动态的加载类呢? 为什么不直接初始化一个Policy类呢? 这难道就是策略模式???????
因此我们看一下com.android.internal.policy.impl.Policy的makeNewWindow函数的实现:
public Window makeNewWindow(Context context) {
return new PhoneWindow(context);
}
只是new了一个PhoneWindow, 并返回.关于PhoneWindow的构造过程可以参考page3文件.
page3
在这里我们看一下PolicyManager的创建过程, 我们先来看一下PolicyManager类的继承体系:
public class PhoneWindow extends Window implements MenuBuilder.Callback
public abstract class Window
PhoneWindow的构造函数如下:
1 public PhoneWindow(Context context) {
2 super(context);
3 mLayoutInflater = LayoutInflater.from(context);
4 }
第2行(PhoneWindow->PhoneWindow)会调用父类的构造函数, Window类的构造函数如下:
public Window(Context context) {
mContext = context;
}
Window类的构造函数除了初始化mContext之外, 什么也没干. 这样就说明, Window会拿着一个Context实例.
第3行(PhoneWindow->PhoneWindow)会调用LayoutInflater的from函数来获得一个LayoutInflater对象并初始化成员变量mLayoutInflater. 关于LayoutInflater的from函数的详细分析可以参考page4文件.
page4
这里我们分析一下LayoutInflater的创建过程, 也就是LayoutInflater的from函数的调用过程:
1 public static LayoutInflater from(Context context) {
2 LayoutInflater LayoutInflater =
3 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
4 if (LayoutInflater == null) {
5 throw new AssertionError("LayoutInflater not found.");
6 }
7 return LayoutInflater;
8 }
第2-3行(LayoutInflater->from)会调用Context的getSystemService来得到一个LAYOUT_INFLATER_SERVICE服务, 哦!!!解析layout是作为一个服务存在的啊, 那就是Binder喽!
这里Context其实是个Activity对象, 因此这里其实会调用Activity的getSystemService函数, Activity的getSystemService函数的定义如下:
1 public Object getSystemService(String name) {
2 if (getBaseContext() == null) {
3 throw new IllegalStateException(
4 "System services not available to Activities before onCreate()");
5 }
6
7 if (WINDOW_SERVICE.equals(name)) {
8 return mWindowManager;
9 } else if (SEARCH_SERVICE.equals(name)) {
10 ensureSearchManager();
11 return mSearchManager;
12 }
13 return super.getSystemService(name);
14 }
第13行(Activity->getSystemService)会调用父类ContextThemeWrapper类的getSystemService函数, ContextThemeWrapper类的getSystemService函数的定义如下:
1 @Override public Object getSystemService(String name) {
2 if (LAYOUT_INFLATER_SERVICE.equals(name)) {
3 if (mInflater == null) {
4 mInflater = LayoutInflater.from(mBase).cloneInContext(this);
5 }
6 return mInflater;
7 }
8 return mBase.getSystemService(name);
9 }
第2-7行(ContextThemeWrapper->getSystemService)又会调用LayoutInflater.from(mBase), 我靠, 这不死循环了么? 注意啊, 这是mBase, mBase其实是个ContextImpl类型的, 因此这里会调用ContextImpl的
getSystemService函数, 关于ContextImpl的getSystemService函数的详细分析可以参考page5文件.
我们开始分析一下Activity的Window和WindowManager的创建过程, 在Activity的attach函数中, 不仅会创建Context, 还会创建Window和WindowsManager对象.因此我们就从Activity的attach函数开始分析:
1 final void attach(Context context, ActivityThread aThread,
2 Instrumentation instr, IBinder token, int ident,
3 Application application, Intent intent, ActivityInfo info,
4 CharSequence title, Activity parent, String id,
5 NonConfigurationInstances lastNonConfigurationInstances,
6 Configuration config) {
7 attachBaseContext(context);
8
9 mFragments.attachActivity(this, mContainer, null);
10
11 mWindow = PolicyManager.makeNewWindow(this);
12 mWindow.setCallback(this);
13 mWindow.getLayoutInflater().setPrivateFactory(this);
14 if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
15 mWindow.setSoftInputMode(info.softInputMode);
16 }
17 if (info.uiOptions != 0) {
18 mWindow.setUiOptions(info.uiOptions);
19 }
20 mUiThread = Thread.currentThread();
21
22 mMainThread = aThread;
23 mInstrumentation = instr;
24 mToken = token;
25 mIdent = ident;
26 mApplication = application;
27 mIntent = intent;
28 mComponent = intent.getComponent();
29 mActivityInfo = info;
30 mTitle = title;
31 mParent = parent;
32 mEmbeddedID = id;
33 mLastNonConfigurationInstances = lastNonConfigurationInstances;
34
35 mWindow.setWindowManager(
36 (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
37 mToken, mComponent.flattenToString(),
38 (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
39 if (mParent != null) {
40 mWindow.setContainer(mParent.getWindow());
41 }
42 mWindowManager = mWindow.getWindowManager();
43 mCurrentConfig = config;
44 }
第11行(Activity->attach)会调用PolicyManager的makeNewWindow函数来为这个Activity创建一个Window, 关于PolicyManager的makeNewWindow函数的详细分析可以参考page2文件.
private Window mWindow;
第12行(Activity->attach)会将mWindow的callback设置成当前activity, 这样mWindow就能将一些事件交给acticity去执行
第13-19行(Activity->attach)会设置Window的一些属性, 我们先不关心.
第35-38行(Activity->attach)会调用Window的setWindowManager函数, setWindowManager函数详细分析可以参考page6文件.
第39-41行(Activity->attach)会判断该Activity的mParent是否不为空, 如果不为空则会为Window的setContainer来设置成mParent的Window. 关于setContainer函数的详细分析可以参考page11文件.
第42行(Activity->attach)会调用Window的getWindowManager来得到WindowManager, 这样每一个Activity实例都会拿着一个WindowManager对象了.
page2
PolicyManager的makeNewWindow函数的定义如下:
public static Window makeNewWindow(Context context) {
return sPolicy.makeNewWindow(context);
}
PolicyManager的makeNewWindow函数只是简单地调用静态成员变量sPolicy的makeNewWindow函数, sPolicy的定义和初始化如下:
private static final String POLICY_IMPL_CLASS_NAME =
"com.android.internal.policy.impl.Policy";
private static final IPolicy sPolicy;
static {
// Pull in the actual implementation of the policy at run-time
try {
Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME);
sPolicy = (IPolicy)policyClass.newInstance();
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
POLICY_IMPL_CLASS_NAME + " could not be loaded", ex);
} catch (InstantiationException ex) {
throw new RuntimeException(
POLICY_IMPL_CLASS_NAME + " could not be instantiated", ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException(
POLICY_IMPL_CLASS_NAME + " could not be instantiated", ex);
}
}
可以看到sPolicy其实是加载的com.android.internal.policy.impl.Policy类, 为什么要动态的加载类呢? 为什么不直接初始化一个Policy类呢? 这难道就是策略模式???????
因此我们看一下com.android.internal.policy.impl.Policy的makeNewWindow函数的实现:
public Window makeNewWindow(Context context) {
return new PhoneWindow(context);
}
只是new了一个PhoneWindow, 并返回.关于PhoneWindow的构造过程可以参考page3文件.
page3
在这里我们看一下PolicyManager的创建过程, 我们先来看一下PolicyManager类的继承体系:
public class PhoneWindow extends Window implements MenuBuilder.Callback
public abstract class Window
PhoneWindow的构造函数如下:
1 public PhoneWindow(Context context) {
2 super(context);
3 mLayoutInflater = LayoutInflater.from(context);
4 }
第2行(PhoneWindow->PhoneWindow)会调用父类的构造函数, Window类的构造函数如下:
public Window(Context context) {
mContext = context;
}
Window类的构造函数除了初始化mContext之外, 什么也没干. 这样就说明, Window会拿着一个Context实例.
第3行(PhoneWindow->PhoneWindow)会调用LayoutInflater的from函数来获得一个LayoutInflater对象并初始化成员变量mLayoutInflater. 关于LayoutInflater的from函数的详细分析可以参考page4文件.
page4
这里我们分析一下LayoutInflater的创建过程, 也就是LayoutInflater的from函数的调用过程:
1 public static LayoutInflater from(Context context) {
2 LayoutInflater LayoutInflater =
3 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
4 if (LayoutInflater == null) {
5 throw new AssertionError("LayoutInflater not found.");
6 }
7 return LayoutInflater;
8 }
第2-3行(LayoutInflater->from)会调用Context的getSystemService来得到一个LAYOUT_INFLATER_SERVICE服务, 哦!!!解析layout是作为一个服务存在的啊, 那就是Binder喽!
这里Context其实是个Activity对象, 因此这里其实会调用Activity的getSystemService函数, Activity的getSystemService函数的定义如下:
1 public Object getSystemService(String name) {
2 if (getBaseContext() == null) {
3 throw new IllegalStateException(
4 "System services not available to Activities before onCreate()");
5 }
6
7 if (WINDOW_SERVICE.equals(name)) {
8 return mWindowManager;
9 } else if (SEARCH_SERVICE.equals(name)) {
10 ensureSearchManager();
11 return mSearchManager;
12 }
13 return super.getSystemService(name);
14 }
第13行(Activity->getSystemService)会调用父类ContextThemeWrapper类的getSystemService函数, ContextThemeWrapper类的getSystemService函数的定义如下:
1 @Override public Object getSystemService(String name) {
2 if (LAYOUT_INFLATER_SERVICE.equals(name)) {
3 if (mInflater == null) {
4 mInflater = LayoutInflater.from(mBase).cloneInContext(this);
5 }
6 return mInflater;
7 }
8 return mBase.getSystemService(name);
9 }
第2-7行(ContextThemeWrapper->getSystemService)又会调用LayoutInflater.from(mBase), 我靠, 这不死循环了么? 注意啊, 这是mBase, mBase其实是个ContextImpl类型的, 因此这里会调用ContextImpl的
getSystemService函数, 关于ContextImpl的getSystemService函数的详细分析可以参考page5文件.
发表评论
-
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:31 543page5 在这篇文章中, 我们分析一下ContextImp ... -
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的直接管理者。
- `addView()`:添加一个View到Window,这通常发生在Activity的`setContentView()`方法中。`WindowManagerGlobal`会创建`ViewRootImpl`实例,然后将View、布局参数和Display信息关联起来。 - `updateViewLayout()`...
1. 当一个Activity启动时,系统会为该Activity创建一个默认的Window。这个Window通常是一个PhoneWindow,包含了DecorView,它是根ViewGroup,用于承载应用的布局。 2. Activity中的setContentView方法实际上是在...
创建一个Window,需要通过WindowManager即可完成,WindowManager是外界访问Window的入口,Window具体实现位于WindowManagerService中,WindowManager和WindowManagerService的交互是一个IPC的过程。Android中,所有...
总的来说,使用WindowManager和Service创建弹窗是一种高级的Android编程技巧,可以为用户提供非传统界面交互体验。但需要注意的是,这种做法需要谨慎处理权限和用户体验问题,避免对系统造成干扰或者滥用权限。
- 使用`WindowManager`服务,通常在`Service`或`Activity`中初始化`WindowManager`实例:`WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);` - 创建一个`LayoutParam`对象,定义...
Activity启动流程是Android系统中一个非常核心的部分,它是应用程序组件之一,负责创建和管理应用的用户界面。当我们想要启动一个新的Activity时,背后有一系列复杂的交互过程,涉及多个组件和类。本文将通过代码...
WindowManager是Android系统中管理窗口的一个关键组件,负责管理所有的窗口,包括应用窗口、子窗口和系统窗口。WindowManager继承了ViewManager接口,提供了三个方法来操作View:addView、updateViewLayout和...
在Android系统中,WindowManager服务负责管理所有应用的窗口,而Activity实际上就是一种特殊的Window。默认情况下,Activity会全屏显示,但我们可以通过修改Activity的属性和使用自定义布局来改变这一行为。 1. ...
最近有学生做毕业设计,想使用悬浮窗这种效果,其实很简单,我们可以通过系统服务WindowManager来实现此功能,本章我们来试验一下在当前Activity之上创建一个悬浮的view。 第一步:认识WindowManager 这个接口用于与 ...
`attach`函数使得Activity能够访问到系统的各种服务,如`WINDOW_SERVICE`,从而能够创建和管理窗口。 在当前Activity中,`PhoneWindow`被实例化,它是Activity的窗口实现。`PhoneWindow`设置回调,然后通过`...
首先,我们需要创建一个悬浮窗口(Floating Window),这是`WindowManager`的主要用途之一。悬浮窗口可以覆盖在其他应用之上,我们可以通过监听悬浮窗口的触摸事件来捕获Home键的按下情况。 1. **添加权限**:在...
本篇将深入探讨如何利用`WindowManager`来创建一个悬浮窗(Floating Window)的demo。 首先,悬浮窗的本质是在应用程序的主窗口之上添加一个额外的窗口。这种窗口通常具有较低的层级,以便它始终位于其他应用窗口之...
本教程将深入讲解如何使用`WindowManager`服务来创建和管理Android悬浮窗,并通过一个简单的Demo——WindowManagerDemo来展示其实现过程。 首先,我们要理解`WindowManager`是Android系统提供的一个接口,它允许...
本文将深入探讨如何利用`WindowManager`服务和布局参数来创建这样的悬浮视频播放窗口。 首先,`WindowManager`是Android系统提供的一个接口,它允许我们添加、移除或更新视图到系统的窗口管理器中。`addView()`方法...
在Android开发过程中,`WindowManager.LayoutParams`是一个非常重要的类,它用于配置窗口的各种属性,如位置、大小、类型等。通过本文档,我们将深入探讨`WindowManager.LayoutParams`的所有参数及其详细信息。 ###...
- **PhoneWindow**: 创建PhoneWindow的过程实际上就是在Activity内部创建一个`PhoneWindow`实例。这个过程会涉及到一些窗口的初始化工作,比如设置布局和添加装饰视图。 #### setContentView `setContentView`是...
在Android中实现悬浮Activity,首先需要创建一个新的Activity,并在布局文件中设置其样式为Dialog样式。这可以通过修改`<style>`标签中的`parent`属性为`Theme.AppCompat.Dialog`来实现。同时,为了使Activity浮现在...
总结,创建一个`WindowManager`实现的悬浮窗口,关键在于设置正确的`LayoutParams`,包括类型、标志和初始位置。同时,通过监听触摸事件,可以实现窗口的自由移动。这个示例中的`FloatViewDemo`应该包含上述代码的...