Activity,ServiceとContext

8095 ワード

Activityの作成プロセス

ActivityThread.javaに遡るperformLaunchActivityメソッド:
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
          //1.  LoadedApk 
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

       .......

      //2.  ContextImpl   appContext
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
          //3.   Activity   
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }

        try {
            //4.  Application   app
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            ........
              //appContext  ContextImpl  , activity  
                appContext.setOuterContext(activity);
              //appContext window 
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigpurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);

               ......
              
                activity.mCalled = false;
                if (r.isPersistable()) {
                    //5.   activity   onCreate  
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                ........
        return activity;
    }

1.LoadedApkオブジェクトを取得する.ContextImplオブジェクトappContextを作成する.Activityオブジェクトactivityを作成する.Applicationオブジェクトappを作成する.activityを呼び出すonCreateメソッド起動

サービス作成プロセス

serviceの作成とactivityの作成は類似しています.ActivityThread.javahandleCreateServiceメソッド:
private void handleCreateService(CreateServiceData data) {
      .....
        //1.  LoadedApk  
        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
      //2.  service  
        Service service = null;
        try {
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = (Service) cl.loadClass(data.info.name).newInstance();
        } catch (Exception e) {
           ....
        }

        try {
          .....
          // 3.  ContextImpl   context
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
          //4.  Application  app
            Application app = packageInfo.makeApplication(false, mInstrumentation);
          
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
        //5.  service   onCreate  
            service.onCreate();
            mServices.put(data.token, service);
            .....
        } catch (Exception e) {
            ......
        }
    }

1.LoadedApkオブジェクトを取得する.serviceオブジェクト3を作成する.ContextImplオブジェクトcontext 4を作成する.Applicationオブジェクトapp 5を作成する.Serviceを呼び出すonCreateメソッドApplicationは最終的にInstrumentation.javanewApplication()メソッドによって作成された.
 static public Application newApplication(Class> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }

ここでは、ContextImplsetOuterContextに設定されているcontextの違いを発見しました.
  • performLaunchActivity ------ activity
  • //appContext  ContextImpl  
    appContext.setOuterContext(activity);
    
  • makeApplication ----- application
  • Application app = null;
    .....
    appContext.setOuterContext(app);
    
  • handleCreateService ---- service
  • context.setOuterContext(service);
    

    Activity contextの作成

    ContextImpl appContext = createBaseContextForActivity(r);
    private ContextImpl createBaseContextForActivity(ActivityClientRecord r) {
           ....
            // appContext,  
            ContextImpl appContext = ContextImpl.createActivityContext(
                    this, r.packageInfo, r.activityInfo, r.token, displayId, r.overrideConfig);
         ....
            return appContext;
        }
    
    static ContextImpl createActivityContext(ActivityThread mainThread,
                LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
                Configuration overrideConfiguration) {
          .....
        //  ContextImpl  
            ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName,
                    activityToken, null, 0, classLoader);
    
            // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
            displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;
    
            final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
                    ? packageInfo.getCompatibilityInfo()
                    : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
    
            final ResourcesManager resourcesManager = ResourcesManager.getInstance();
    
            // Create the base resources for which all configuration contexts for this Activity
            // will be rebased upon.
            //  resources        
            context.setResources(resourcesManager.createBaseActivityResources(activityToken,
                    packageInfo.getResDir(),
                    splitDirs,
                    packageInfo.getOverlayDirs(),
                    packageInfo.getApplicationInfo().sharedLibraryFiles,
                    displayId,
                    overrideConfiguration,
                    compatInfo,
                    classLoader));
            context.mDisplay = resourcesManager.getAdjustedDisplay(displayId,
                    context.getResources());
            return context;
        }
    

    Service context作成

    ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
    
    
    createAppContextメソッド:
    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
            if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
            ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
                    null);
            context.setResources(packageInfo.getResources());
            return context;
        }
    

    以上、このActivityServiceContextとのつながりを調べてみました.