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。