Android深入理解Context--Service中Context的創建過程

本系列分四篇文章詳細介紹Context, 這是第三篇

  • Android深入理解Context–Application中Context的創建過程

  • Android深入理解Context–Activity中Context的創建過程

  • Android深入理解Context–Service中Context的創建過程

  • Android深入理解Context–Context使用的誤區

  • 因爲本文是分析Service的Context創建流程,我們直接從ActivityThread.handleCreateService開始分析,如果不太明白這之前的邏輯的話,可以參考Service啓動流程源碼分析

    @UnsupportedAppUsage
        private void handleCreateService(CreateServiceData data) {
            // If we are getting ready to gc after going to the background, well
            // we are back active so skip it.
            unscheduleGcIdler();
    
            LoadedApk packageInfo = getPackageInfoNoCheck(
                    data.info.applicationInfo, data.compatInfo);
            Service service = null;
            try {
                //-----1-----
                java.lang.ClassLoader cl = packageInfo.getClassLoader();
                service = packageInfo.getAppFactory()
                        .instantiateService(cl, data.info.name, data.intent);
            } catch (Exception e) {
                if (!mInstrumentation.onException(service, e)) {
                    throw new RuntimeException(
                        "Unable to instantiate service " + data.info.name
                        + ": " + e.toString(), e);
                }
            }
    
            try {
                if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
                //-----2-----
                ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
    
                //-----3-----
                context.setOuterContext(service);
                //-----4-----
                Application app = packageInfo.makeApplication(false, mInstrumentation);
                //-----5-----
                service.attach(context, this, data.info.name, data.token, app,
                        ActivityManager.getService());
                //-----6-----
                service.onCreate();
                mServices.put(data.token, service);
                try {
                    ActivityManager.getService().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                } catch (RemoteException e) {
                    throw e.rethrowFromSystemServer();
                }
            } catch (Exception e) {
                if (!mInstrumentation.onException(service, e)) {
                    throw new RuntimeException(
                        "Unable to create service " + data.info.name
                        + ": " + e.toString(), e);
                }
            }
        }
    
  • 註釋1處創建一個service對象。

  • 註釋2處創建一個Service的ContextImpl對象。

  • 註釋3setOuterContext將service對象賦值給ContextImpl中的mOuterContext, 這樣ContextImpl就可以訪問service中的方法和變量了。

  • 註釋4處創建一個Application,在前面Android深入理解Context講過。

  • 註釋5處調用service.attach,將創建的context傳遞進service中。

  • 註釋6處調用service.onCreate()

  • 我們主要看下注釋4的代碼部分,進入service.attach

    public abstract class Service extends ContextWrapper {
        @UnsupportedAppUsage
        public final void attach(
                Context context,
                ActivityThread thread, String className, IBinder token,
                Application application, Object activityManager) {
            attachBaseContext(context);
            mThread = thread;           // NOTE:  unused - remove?
            mClassName = className;
            mToken = token;
            mApplication = application;
            mActivityManager = (IActivityManager)activityManager;
            mStartCompatibility = getApplicationInfo().targetSdkVersion
                    < Build.VERSION_CODES.ECLAIR;
        }
    }
    
    public class ContextWrapper extends Context {
        protected void attachBaseContext(Context base) {
            if (mBase != null) {
                throw new IllegalStateException("Base context already set");
            }
            mBase = base;
        }
    }
    
  • 最終還是將Service類型的ContextImpl賦值給了ContextWrapper中的mBase變量,這樣我們調用ContextWrapper中的方法實際就是調用mBase這個真正的ContextImpl中的方法。

  • 至此我們關於Service的Context的分析就結束了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章