Android-Context、Window基础解析
本文最后更新于 660 天前
1. Context

Context是应用程序与系统之间沟通的桥梁,是应用程序访问系统资源的接口

Context文章源链接

  • 使用到了装饰者模式,把封装操作实现在ContextImpl中。
  • ContextProvider使用的是Application的context,Broadcast使用的是activity的context
  • Activity的getBaseContext,即ContextImpl 真正的Context接口的逻辑实现类
  • 使用Application启动的Activity必须指定task以及标记为singleTask,因为Application是没有任务栈的,需要重新开一个新的任务栈
  • Application创建:(类加载和反射)
    1. ActivityThread类 -> performLaunchActivity方法内的 makeApplication
    2. LoadedApk类 -> makeApplication方法内
      2.1 ContextImpl.createAppContext 创建ContextImpl实例
      2.2 mActivityThread.mInstrumentation.newApplication 创建Application
      2.3 ContextImpl.setOuterContext(app); 将Application赋值给ContextImpl

**

以下都是相关通过attach附加

**

Instrumentation.class(api29)
// 这里的context 就是ContextImpl
public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);
    app.attach(context);
    return app;
}

Application.class(api29)
final void attach(Context context) {
    attachBaseContext(context);
    mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

ContextWrapper.class(api29)
Context mBase;
protected void attachBaseContext(Context base) {
    if (mBase != null) {
        throw new IllegalStateException("Base context already set");
    }
    mBase = base;
}
  • Activity创建 (类加载和反射)
    1. ActivityThread类 -> handleLaunchActivity方法内的 performLaunchActivity
    2. performLaunchActivity方法内:mInstrumentation.newActivity、r.packageInfo.makeApplication(同上)
  • Service创建 (类加载和反射)
    1. ActivityThread类 > handleCreateService方法
    2. 类加载和反射创建service,随后创建ContextImpl,并同上诉一样调用attach
  • BroadCast创建
    • ContextImple类 -> registerReceiver方法 -> registerReceiverInternal
    • registerReceiverInternal -> ReceiverDispatcher中有个InnerReceiver(Receiver是没有跨进程通信能力的,而广播需要AMS的调控,InnerReceiver是维护联系的)
    • registerReceiverInternal的参数 getOuterContext() 获取的就是创建广播的上下文Context,一般都是在Activity内创建,所以这个Context一般都是Activity。
  • ContextProvider创建
    1. ActivityThread类 > handleBindApplication方法 installContentProviders
    2. installContentProviders方法 installProvider
      2.1 localProvider.getIContentProvider() 创建ContentProvider
      2.2 调用attachInfo 将 Context等相关信息附加
2. Window

Window原文章链接
– viewRootImpl是window和view之间的桥梁,viewRootImpl可以处理两边的对象,然后联结起来
1. setView方法内的 mWindowSession是一个AIDL,可以调用WMS方法

// 一个应用只有一个IWindowSession单例。
public static IWindowSession getWindowSession() {
 synchronized (WindowManagerGlobal.class) {
     if (sWindowSession == null) {
         try {
             ...
             sWindowSession = windowManager.openSession(
                     new IWindowSessionCallback.Stub() {
                         ...
                     });
         } 
         ...
     }
     return sWindowSession;
 }
}

window的添加过程是通过PhoneWindow对应的WindowManagerImpl来添加window,内部会调用WindowManagerGlobal来实现。WindowManagerGlobal会使用viewRootImpl来进行跨进程通信让WMS执行创建window的业务。
每个应用都有一个windowSession,用于负责和WMS的通信,如ApplicationThread与AMS的通信。
– PhoneWindow本身不是真正意义上的window,他更多可以认为是辅助Activity操作window的工具类。
– windowManagerImpl并不是管理window的类,而是管理PhoneWindow的类。真正管理window的是WMS。
– PhoneWindow可以配合DecorView可以给其中的window按照一定的逻辑提供标准的UI策略
– PhoneWindow限制了不同的组件添加window的权限(内部有一个token属性)。

2.1 Activity的Window创建
  • Activity中使用getWindowManager方法获取到的就是应用的PhoneWindow对应的WindowManagerImpl
    1. attach方法内创建了PhoneWindow,并mWindow.setWindowManager 将PhoneWindow和WindowManager绑定
    2. setWindowManager方法内 设置mAppToken,创建mWindowManager(WindowManagerImpl)
    3. attach后会回调onCreate方法,onCreate内会生成DecorView并设置相关的布局
    4. ActivityThread的handleResumeActivity方法中 会回调Activity的onResume方法,而onResume方法内就包含了 WindowManager.addView 将DecorView添加到视图上
      >创建PhoneWindow -> 创建WindowManager -> 创建decorView -> 利用windowManager把DecorView显示到屏幕上
      >回调onResume方法的时候,DecorView还没有被添加到屏幕,所以当onResume被回调,指的是屏幕即将到显示,而不是已经显示
2.2 PopupWindow的Window创建
  • 根据参数构建popupDecorView
  • 把popupDecorView添加到屏幕上
2.3 Dialog的Window创建 (与Activity类似)
  • dialog和popupWindow不同,dialog创建了新的PhoneWindow,使用了PhoneWindow的DecorView模板。而popupWindow没有
  • dialog的显示层级数更高,会直接显示在Activity上面,在dialog后添加的popUpWindow也会显示在dialog下
2.4 总结
  • PhoneWindows和WindowManagerImpl
  • 添加View => WindowManagerGlobal获取Session,创建一个ViewRootImpl去访问WMS,在使用ViewRootImpl去绘制View。 WindowManagerImpl内部持有WindowManagerGlobal这样就简单易操作
  • PhoneWindow只是对Window的封装,内部持有DecorView,并可以通过ViewRootImpl进View的操作
  • PhoneWindow内部只持有一个decorView,只管理一个view 树,并不是window 容器;PhoneWindow只是提供了 token 机制来校验子window的合法性
iichen:https://iichen.cn/?p=421
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇