Android Context 原理
来源:互联网 发布:sql server 按照工作日 编辑:程序博客网 时间:2024/05/15 09:59
原文:https://sites.google.com/site/terrylai14/home/android-context-yuan-li
Context,中文可以翻譯成"場景",SDK說明如下:Interface to global information about an application environment. This is an abstract class whose implementationis provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc
由此可知以下三點:
1、他描述的是一個應用程式的場景
2、context是一個抽象類別abstract,Android提供了此抽象類別的具體實現(ContextIml)
3、透過context我們可以取得應用程式的資源,包含一些應用層的操作,像是啟動activity 發送broadcast等
先來看看Context的架構吧
架構介紹:
Context Path: /frameworks/base/core/java/android/content/Context.java
說明: abstract,提供了通用的API。
部分source code:
- public abstract class Context {
- ...
- public abstract Object getSystemService(String name); //取得系統級別服務
- public abstract void startActivity(Intent intent); //透過一個intent啟動activity
- public abstract ComponentName startService(Intent service); //啟動Service
- //根據文件名稱取得SharedPreferences 對象
- public abstract SharedPreferences getSharedPreferences(String name,int mode);
- ...
- }
ContextIml.java Path :/frameworks/base/core/java/android/app/ContextImpl.java
說明:這個Context類別的實現為ContextIml,這類別實現了Context類別的功能。這個函数的大部分功能都是直接調用其属性mPackageInfo去完成。
部分source code:
- /**
- * Common implementation of Context API, which provides the base
- * context object for Activity and other application components.
- */
- class ContextImpl extends Context{
- //所有Application共同使用一個mPackageInfo對象
- /*package*/ ActivityThread.PackageInfo mPackageInfo;
- @Override
- public Object getSystemService(String name){
- ...
- else if (ACTIVITY_SERVICE.equals(name)) {
- return getActivityManager();
- }
- else if (INPUT_METHOD_SERVICE.equals(name)) {
- return InputMethodManager.getInstance(this);
- }
- }
- @Override
- public void startActivity(Intent intent) {
- ...
- //啟動一個activity
- mMainThread.getInstrumentation().execStartActivity(
- getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);
- }
- }
ContextWrapper Path :\frameworks\base\core\java\android\content\ContextWrapper.java
說明: 此類別只是對Context類別的一層包裝,這個類別的構造函數包含了一個真正的context引用,即ContextIml
部分source code:
- public class ContextWrapper extends Context {
- Context mBase; //這属性指向一個ContextIm實例,一般在創建Application、Service、Activity時給予值
- //創建Application、Service、Activity,會調用該方法給mBase賦予值
- protected void attachBaseContext(Context base) {
- if (mBase != null) {
- throw new IllegalStateException("Base context already set");
- }
- mBase = base;
- }
- @Override
- public void startActivity(Intent intent) {
- mBase.startActivity(intent);
- }
- }
ContextThemeWrapper
Path:/frameworks/base/core/java/android/view/ContextThemeWrapper.java
說明:此類別內部包含了Theme相關的接口,這邊的值由android:theme所指定。只有Activity需要Theme,Service不需要Theme,所以Service直接繼承ContextWrapper類別。
源代码(部分)如下:
- public class ContextThemeWrapper extends ContextWrapper {
- //這属性指向一個ContextIm實例,一般在創建Application、Service、Activity時給予值
- private Context mBase;
- //mBase赋值方式同樣有以下兩種
- public ContextThemeWrapper(Context base, int themeres) {
- super(base);
- mBase = base;
- mThemeResource = themeres;
- }
- @Override
- protected void attachBaseContext(Context newBase) {
- super.attachBaseContext(newBase);
- mBase = newBase;
- }
- }
Activity 、Service 、Application本質上都是Context子類別, 更多imformation大家可以自行参考source code
什麼時候創建Context?
了解了Context繼承關係以後,接下來分析應用程式在什麼情況下需要創建Context對象? 應用程式創建Context實例的情況有以下幾種:
1、創建Application時, 而且整個App共一個Application對象
2、創建Service對象時
3、創建Activity對象時
由此可知一個app所擁有的Context個數是:
Service個數 + Activity個數 + 1(Application對應的Context實例)
具體創建Context的時機
1、創建Application對象的時機
每個應用程式第一次啟動的時候,都會先建立一個Application。
如果要跟應用程式啟動一個Activity流程比較的話,創建Application的時機在創建handleBindApplication()方法中,此函式在 ActivityThread.java類別中 ,如下:
- //創建Application時同時創建ContextIml實例
- private final void handleBindApplication(AppBindData data){
- ...
- ///創建Application對象
- Application app = data.info.makeApplication(data.restrictedBackupMode, null);
- ...
- }
- public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
- ...
- try {
- java.lang.ClassLoader cl = getClassLoader();
- ContextImpl appContext = new ContextImpl(); //創建一個ContextImpl對象實例
- appContext.init(this, null, mActivityThread); //初始化ContextIml的相關屬性
- ///新建一個Application對象
- app = mActivityThread.mInstrumentation.newApplication(
- cl, appClass, appContext);
- appContext.setOuterContext(app); //將Application實例傳給ContextImpl
- }
- ...
- }
2、創建Activity對象的時機
透過startActivity()或startActivityForResult()要求啟動一個Activity時,如果系统檢測需要新建一個Activity時,就會使用handleLaunchActivity(),這個方法在調用performLaunchActivity(),去創建一個Activity,並且回調onCreate(),onStart()方法等, 函式都位於 ActivityThread.java類別 ,如下:
- private final void handleLaunchActivity(ActivityRecord r, Intent customIntent) {
- ...
- Activity a = performLaunchActivity(r, customIntent); //啟動一個Activity
- }
- private final Activity performLaunchActivity(ActivityRecord r, Intent customIntent) {
- ...
- Activity activity = null;
- try {
- //創建一個Activity實例
- java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
- activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
- }
- if (activity != null) {
- ContextImpl appContext = new ContextImpl(); //創建一個Activity實例
- appContext.init(r.packageInfo, r.token, this); //初始化ContextIml的相關屬性
- appContext.setOuterContext(activity); //將Activity訊息傳遞给ContextImpl實例
- ...
- }
- ...
- }
3、創建Service對象的時機
透過startService或者bindService,如果系统檢測到需要新建一個Service實例,就會使用handleCreateService(),完成相關數據操作。handleCreateService()函數位於 ActivityThread.java,如下:
- private final void handleCreateService(CreateServiceData data){
- ...
- //創建一個Service實例
- Service service = null;
- try {
- java.lang.ClassLoader cl = packageInfo.getClassLoader();
- service = (Service) cl.loadClass(data.info.name).newInstance();
- } catch (Exception e) {
- }
- ...
- ContextImpl context = new ContextImpl(); //創建一個ContextImpl實例
- context.init(packageInfo, null, this); //初始化
- // 獲得之前創建的application的訊息
- Application app = packageInfo.makeApplication(false, mInstrumentation);
- //把Service訊息傳遞给ContextImpl實例
- context.setOuterContext(service);
- ...
- }
- Android Context 原理
- Android之Context底层原理
- Android Context原理与使用的总结
- Android Context原理与使用的总结
- Android Context原理与使用的总结
- Android Context原理与使用的总结
- Android-Context原理与用法详解
- Android面试题-Context原理分析
- Android - Context, What Context?
- Android Context, What Context?
- android context
- android context
- android context
- Android Context
- Android-Context
- Android Context
- android context
- Android Context
- iOS JSON解析Web
- android 判断当前环境网络是否可用及获取当前网络类型
- perl 匿名函数传参
- Json 数据解析
- leecode_200 Number of Islands
- Android Context 原理
- iOS时间那点事 NSCalendar + NSDateComponents
- Light-lda部署安装过程
- 自定义进度条
- Google Protocol Buffer 的使用和原理
- Android架构学习MVC、MVP、MVVM(一)
- js判断输入字符串是否为空、空格、null总结
- Windows下基于UDP的可靠传输协议实现
- Linux进程与线程的区别