Android四大组件之Activity(七)——新创建的进程Android Context

本文探讨了Android中Context的使用场景,包括启动Activity、Service、发送广播等,并解析了Context类图,强调ContextImpl和ContextWrapper在其中的作用。文章指出,Application、Activity和Service通过attach()方法与ContextImpl建立联系,而真正执行Context功能的是ContextImpl。同时,解释了为何不直接使用ContextImpl以及四大组件与Application的关系。
摘要由CSDN通过智能技术生成

1、使用的是Android 7.1.2的源代码:

https://pan.baidu.com/s/1XcVD68cC_2wKtm8jJkdNQA
przv

2、感谢IT先森的系列博客:

Android应用进程创建流程大揭秘
Android四大组件之bindService源码实现详解
Android四大组件之Activity启动流程源码实现详解概要
Activity启动流程(一)发起端进程请求启动目标Activity
Activity启动流程(二)system_server进程处理启动Activity请求
Activity启动流程(三)-Activity Task调度算法复盘分析
Activity启动流程(四)-Pause前台显示Activity,Resume目标Activity
Activity启动流程(五)请求并创建目标Activity进程
Activity启动流程(六)注册目标Activity进程到system_server进程以及创建目标Activity进程Application
Activity启动流程(七)初始化目标Activity并执行相关生命周期流程

1、Context的使用场景

  • 启动Activity(startActivityXXX(…)方法族)
  • 启动/停止Service(startServiceXXX(…)/stopServiceXXX(…)方法族)
  • 绑定/解绑Service(bindServiceXXX(…)/unbindService(…)方法族)
  • 发送广播(sendBroadcastXXX(…)/sendOrderedBroadcastXXX(…)方法族)
  • 注册/注销广播(registerReceiverXXX(…)/unregisterReceiver(…)方法族)
  • 获取ContentResolver(getContentResolver(…))
  • 获取类加载器 (getClassLoader(…))
  • 数据库(SQLite)相关,包括打开数据库、删除数据库、获取数据库路径等(openOrCreateDatabase(…)方法族)
  • 获取各种资源相关方法(getResources()/getString(…)/getColor(…)系列方法族)
  • 文件,包括获取缓存文件夹、删除文件、SharedPreference 相关等功能(getSharedPreferences(…)等系列方法族)

四大组件以及各种资源的操作都离不开Context。

但是Context类是一个抽象类。

2、Context类图

在这里插入图片描述

  • Context有两个直接继承子类:ContextImpl和ContextWrapper,ContextWrapper又通过mBase指向了ContextImpl,即ContextWrapper的核心工作都是交给ContextImpl来完成的,两者是代理模式。
  • Application/Activity/Service通过attach()调用父类ContextWrapper的attachBaseContext(),从而设置父类成员变量mBase为ContextImpl对象,所以说真正执行Context使命的是ContextImpl。
public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory2,
        Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks2,
        Window.OnWindowDismissedCallback, WindowControllerCallback {
        
       		final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window) {
          		 attachBaseContext(context);
          		 ··· ···
            }
		}
public class ContextThemeWrapper extends ContextWrapper {
    ··· ···
   @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(newBase);
    }
  }
public class ContextWrapper extends Context {
	Context mBase;
    public ContextWrapper(Context base) {
        mBase = base;
    }
    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }
    ··· ···
}

注意:

一般情况下,使用代理,而不直接使用某个对象,目的可能有两个:1、定制自己的行为;2、不影响原对象。

1、对于Service和Application而言,不直接继承ContextImpl,是担心用户修改了ContextImpl而导致错误的发生。
2、对于Activity而言,除了担心用户的修改之外,ContextImpl和Activity本身对于Resource和Theme的相关行为是不同的。

  • Android同一应用中的四大组件都属于同一个Application,其中
    1)Activity/Service,通过调用其方法getApplication(),可主动获取当前所在的mApplication,而且是由LoadedApk.makeApplication()过程所初始化的
    2)Receiver,是通过其方法onReceive()的第一个参数指向通当前所在Application,也就是只有接收到广播的时候才能拿到当前的Application对象
    3)provider,目前没有提供直接获取当前所在Application的方法, 但可通过getContext()可以获取当前的ContextImpl。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值