Android's Application and Resource instantiation process

Application instantiation process

//我们的ActivityThread就是通过这个Handler来通知启动Application的
//并且Activity也是它通知启动的具体可以看ActivityThread中各种handle开头的方法
final H mH = new H();
  //看来还是通过Handler
  public void handleMessage(Message msg) {
        ...
                case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
        ...
    }
 private void handleBindApplication(AppBindData data) {
     ...
     //创建Application实例对象
           // If the app is being launched for full backup or restore, bring it up in
            // a restricted environment with the base application class.
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;
     ...
 }

makeApplication is a method in the LoadedApk class

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
            ...
        Application app = null;
        try {
            java.lang.ClassLoader cl = getClassLoader();
           ...
           //注意这里,这里创建了我们伟大的Context实例
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        }
    }

You can see that the instance object of our Application is created by reflection in Instrumentation

    static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }

Resource instantiation process

Through the analysis of the instantiation object process of Application above, we can see that the instantiated object of Context is ContextImpl, which is very important.

We know that we get the Resource object by calling the getResource() method in the Activity

    @Override
    public Resources getResources() {
    // 可以看到最终调用的是mBase(Context实例)的方法
        return mBase.getResources();
    }
public class ContextWrapper extends Context {
    Context mBase;

    public ContextWrapper(Context base) {
        mBase = base;
    }
    ... 
}

So when is the instance object of mBase created?

//Instrumentation 类
//创建Application实例的时候调用的这个方法
    static public Application newApplication(Class<?> clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }
   /**
     * @hide
     */
    /* package */ final void attach(Context context) {
    //可以看到
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }
   protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        //也就是说mBase实际上就是ContextImpl
        mBase = base;
    }

So see when mResouce is created in ContextImpl

   void setResources(Resources r) {
        if (r instanceof CompatResources) {
            ((CompatResources) r).setContext(this);
        }
        mResources = r;
    }

So far, you can see when this method is called, but in the end you will find that it is the same as the Resources instance object obtained by the getResources method of ResourceManager.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324548601&siteId=291194637