Context都没弄明白?

Context都没弄明白?

Android小彩虹2021-07-09 11:27:40270A+A-

Context 到底是什么?

一个Context意味着一个场景,一个场景就是我们和软件进行交互的一个过程。

从安卓程序的角度来看,其实一个Activity就是一个Context,一个Service也是一个Context。

一个app其实可以理解成一个大环境,在这个环境里,可以切换到不同的场景,比如你早上先去办公室上班,中午到饭馆吃饭,就是在不同的场景了。

各个Context 类的关系图

先贴个图

Context 作用是啥

有什么用?要看它能做啥,看看主要提供了哪些接口了。

四大组件相关
获取系统/应用资源
获取应用相关信息
文件相关
数据库相关
其它

还挺多的,看起来管得挺多,四大组件都管着,像个 Application 大管家。

管的谁? 哪些事?
四大组件 包括启动 Activity、Broadcast、Service,获取 ContentResolver 等
获取系统/应用资源 包括 AssetManager、PackageManager、Resources、System Service 以及 color、string、drawable 等
数据库(SQLite)相关 包括打开数据库、删除数据库、获取数据库路径等
其它辅助功能 比如设置 ComponentCallbacks,即监听配置信息改变、内存不足等事件的发生

ContextImpl 和 ContextWrapper 有啥区别?

看下ContextWrapper的源码吧

/** * Proxying implementation of Context that simply delegates all of its calls to * another Context. Can be subclassed to modify behavior without changing * the original Context. */
public class ContextWrapper extends Context {
    Context mBase; // 注意这个mBase

    public ContextWrapper(Context base) {
        mBase = base;
    }

    /** * Set the base context for this ContextWrapper. All calls will then be * delegated to the base context. Throws * IllegalStateException if a base context has already been set. * * @param base The new base context for this wrapper. */
    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }

    /** * @return the base context as set by the constructor or setBaseContext */
    public Context getBaseContext() {
        return mBase; // 这就是Base Context 了
    }

    @Override
    public AssetManager getAssets() {
        return mBase.getAssets();
    }

    @Override
    public Resources getResources() {
        return mBase.getResources();
    }

    @Override
    public PackageManager getPackageManager() {
        return mBase.getPackageManager();
    }
    ...

    @Override
    public Context getApplicationContext() {
        return mBase.getApplicationContext();
    }
    ...

ContextImpl呢?

/** * Common implementation of Context API, which provides the base * context object for Activity and other application components. */
class ContextImpl extends Context {

    private int mThemeResource = 0;
    private Resources.Theme mTheme = null;
    private @NonNull Resources mResources;
    
    // 用于创建 Activity Context
    static ContextImpl createActivityContext(...) {
        ContextImpl context = new ContextImpl(...);
        context.setResources(resourcesManager.createBaseActivityResources(...));
        return context;
    }
    
    // 用于创建 Application Context、Service Context
    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
        ContextImpl context = new ContextImpl(...);
        context.setResources(packageInfo.getResources());
        return context;
    }
    
    private static Resources createResources(...) {
        return ResourcesManager.getInstance().getResources(...);
    }

    // ContextThemeWrapper 没有重写父类的 setResources
    // 因此会调用 mBase 的 setResources,即和 ContextImpl 的行为一样
    void setResources(Resources r) {
        if (r instanceof CompatResources) {
            ((CompatResources) r).setContext(this);
        }
        mResources = r;
    }
    
    @Override
    public Resources getResources() {
        return mResources;
    }
    ...
Class Diff
ContextImpl 真正实现了Context中所有的函数 (真正厉害的!)
ContextWrapper Context 的代理类,所有的操作都是通过内部成员 mBase 完成的
ContextThemeWrapper 内部包含了与主题相关的接口,有自己的 Theme 以及 Resource,并且 Resource 可以传入自己的配置初始化

P.S.

主题是啥?

就是指在AndroidManifest.xml中通过 android:themeApplication 或者 Activity 指定的主题。

只有Activity才需要主题,Service是默默的后台工作者,不需要穿的那么鲜艳,所以Service直接继承 ContextWrapper 就好了。

Activity、Service、Application 各自的Context有啥区别?

不同组件创建ContextImpl的方式:

API
Activity 调用 createBaseContextForActivity
Service/Application 调用 createAppContext
Provider 调用 createPackageContext
BroadcastReceiver 直接从 Application.getBaseContext() 来获取 ContextImpl 对象

参考:

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1

联系我们