`
zzu_007
  • 浏览: 22511 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Activity的Window和WindowManager的创建过程(一)

阅读更多
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文件.

分享到:
评论

相关推荐

    理解Window和WindowManager

    Window是一个抽象类,具体实现是 PhoneWindow 。不管是 Activity 、 Dialog 、 Toast 它们的视图都是附加在Window上的,因此Window实际上是View的直接管理者。

    深入理解Android中的Window和WindowManager

    创建一个Window,需要通过WindowManager即可完成,WindowManager是外界访问Window的入口,Window具体实现位于WindowManagerService中,WindowManager和WindowManagerService的交互是一个IPC的过程。Android中,所有...

    在当前Activity之上创建悬浮view之WindowManager悬浮窗效果

    最近有学生做毕业设计,想使用悬浮窗这种效果,其实很简单,我们可以通过系统服务WindowManager来实现此功能,本章我们来试验一下在当前Activity之上创建一个悬浮的view。 第一步:认识WindowManager 这个接口用于与 ...

    Android WindowManager悬浮显示歌词

    一个WindowManager悬浮窗,悬浮显示歌词效果。WindowManager背景设置为了透明色,显示的WindowManager关闭启动它的Activity回到主界面仍然有效。仅供参考............

    Android开发艺术探索.任玉刚(带详细书签).pdf

    8.3.1 Activity的Window创建过程 304 8.3.2 Dialog的Window创建过程 308 8.3.3 Toast的Window创建过程 311 第9章 四大组件的工作过程 316 9.1 四大组件的运行状态 316 9.2 Activity的工作过程 318 9.3 Service...

    WindowManagerService相关类图.eddx

    Activity,Window,DecorView,ViewRootImpl,WindowManager,WindowManagerImpl,WindowManagerGlobal,WindowManagerService相关类图

    Android开发艺术探索

     8.3.1 Activity的Window创建过程 / 304  8.3.2 Dialog的Window创建过程 / 308  8.3.3 Toast的Window创建过程 / 311  第9章 四大组件的工作过程 / 316  9.1 四大组件的运行状态 / 316  9.2 Activity的工作过程...

    Android 中 android.view.WindowLeaked的解决办法

    我们知道Android的每一个Activity都有个WindowManager窗体管理器,同样,构建在某个Activity之上的对话框、PopupWindow也有相应的WindowManager窗体管理器。因为对话框、PopupWindown不能脱离Activity而单独存在着,...

    Android编程设定activity进入和退出效果的方法

    设置Dialog首先通过getWindow()方法获取它的窗口,然后通过getAttributes()方法获得window的WindowManager.LayoutParams lp, lp有个公共属性windowAnimations, 只要把要实现的animation的id赋值给它就可以了。...

    Android代码-android-advanced-decode

    《Android进阶解密》源码 源码目录介绍 目录 简介 ...第1章介绍Android系统架构、系统源码目录和如何阅读源码,带领大家走进Android...第7章介绍WindowManager,包括WindowManager的关联类、Window的属性和Window

    通过案例分析Android WindowManager解析与骗取QQ密码的过程

    Windows Manager是一款窗口管理终端,可以远程连接到Linux的X桌面进行管理,...Window&&WindowManager介绍  分析demo之前,先要整理总结一下相关的知识。先看看Window类,Window是一个抽象类,位于代码树frameworks\u0

    android dialog与popwindow之间的简单运用

    注意:PopupWindow组件的使用问题,PopupWindow是一个阻塞对话框,如果你直接在Activity创建的方法中显示它,则会报错:android.view.WindowManager$BadTokenException:Unable to add window -- token null is not ...

    android activity设置无标题实现全屏

    Activity设置全屏和无标题栏,要用到andorid.view.Window和Android.view.WindowManager。 Window.FEATURE_NO_TITLE表示无标题栏。 WindowManager.LayoutParams.FLAG_FULLSCREEN表示全屏。 具体用法如下: 1、设置...

    不依赖于Activity的Android全局悬浮窗的实现

    前言 当我们在手机上使用360安全卫士时,手机屏幕上时刻都会出现一个小浮动窗口,点击该浮动窗口可...通过Context.getSystemService(Context.WINDOW_SERVICE)可以获得 WindowManager对象。 每一个WindowManager对象

    Android窗口机制

    每个Activity都有一个Window对象,这个对象是PhoneWindow类型的。 每个Window对象里面都维护着一个WindowManager对象。 Activity里面添加一个View是通过WindowManager的addView()方法实现的 相关关键类 ...

    音乐播放器(J2ME)

    大家都知道,一般一个Activity设置全屏的方法有两种,一是在OnCreate中: @Override 2 public void onCreate(Bundle icicle) { 3 super.onCreate(icicle); 4 5 requestWindowFeature(Window.FEATURE_NO_...

    Android 设置应用全屏的两种解决方法

    在开发中我们经常需要把我们的应用设置为全屏,有两种方法,一中是在代码中设置,另一种方法是在配置文件里改! 一、在代码中设置: 代码如下:package com.android.tutor; import android.app.Activity; import ...

    Android利用WindowManager实现悬浮窗

    前言 你会发现QQ视频的时候,就算手机回到主页,视频小模块依旧能悬浮在桌面上。还有当年很火的各种手机... 应用Window:对应一个Activity 子Window:不能单独存在,它需要附属在特定的父Window中,比如常见的一些Dial

    Android自定义对话框

    在这种情况下我们想很自由的定义对话框,或者有的时候我们的对话框是一个图片,没有标题和按钮,例如这样的一系列需求,这一篇文章我们来给大家介绍一下如何像使用Activity一样来自定义我们的对话框。 一般自定义...

Global site tag (gtag.js) - Google Analytics