Android应用开发之Activity的Window和WindowManager的创建过程(一)
白羽 2018-08-10 来源 :网络 阅读 1012 评论 0

摘要:本文将带你了解Android应用开发之Activity的Window和WindowManager的创建过程(一),希望本文对大家学Android有所帮助

        本文将带你了解Android应用开发之Activity的Window和WindowManager的创建过程(一),希望本文对大家学Android有所帮助


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文件.    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程