2.0. Context create a variety of process analysis

Activity in the Context creation process analysis

android process running in the application window, you need access to certain resources or classes. These particular resource or classes form the operational context of Android applications, Android application window can interface to access it through a Context, the Context interface is what we often encounter when developing applications. In this article, we will analyze in detail the context of the creation process runs Android application window.

 In front of the implement frame and brief study plan Android application window (Activity) mentioned in the article, Android operating context of the application window class is described by ContextImpl, i.e., each component has associated a Activity ContextImpl object. ContextImpl class inherits the Context class, its relationship with the assembly shown in Figure 1 Activity:

        The class diagram in design mode, which can be referred to as a decorative pattern. Activity component referenced by its parent ContextThemeWrapper and member variables mBase ContextWrapper of a ContextImpl objects, so that you can perform some specific operations by this ContextImpl objects later Activity components, for example, start the Service component , registered radio receiver and start Content Provider assembly operation. Meanwhile, ContextImpl class and through their own member variables mOuterContext to refer to an Activity component associated with it, so, ContextImpl classes can also be forwarded to the Activity some operations component to handle.

        In front of the Android application startup procedure source code analysis article, we have analyzed in detail the process of starting a component of the Activity. In this startup process, the last step is to create a function performLaunchActivity ActivityThread by members of the class in the application process in an Activity instance, and set the context for its operation, that is, it creates a ContextImpl object. Next, we started from the class member functions performLaunchActivity ActivityThread analyze the process of creating an Activity instance, so that you can learn about the process of creating its operational context, as shown below:

This process is divided into a total of 10 steps, then we have a detailed analysis of each step.

Step 1. ActivityThread.performLaunchActivity

 

public final class ActivityThread {
    ......
    Instrumentation mInstrumentation;
    ......
    private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ......
        ComponentName component = r.intent.getComponent();
        ......
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
            ......
        } catch (Exception e) {
            ......
        }

        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            ......
            if (activity != null) {
                ContextImpl appContext = ContextImpl.createActivityContext(this, r.packageInfo, displayId, r.overrideConfig);
                ......
                appContext.setOuterContext(activity);
                ......
                Configuration config = new Configuration(mConfiguration);
                ......
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstance,
                        r.lastNonConfigurationChildInstances, config);
                ......
                mInstrumentation.callActivityOnCreate(activity, r.state);
                ......  
            }
            ......
        } catch (SuperNotCalledException e) {
            ......
        } catch (Exception e) {
            ......
        }
        return activity;
    }
}

 

Step 2. Instrumentation.newActivity

 

class ContextImpl extends Context {  
    ......  
  
    private Context mOuterContext;  
    ......  
  
    ContextImpl() {  
        // For debug only  
        //++sInstanceCount;  
        mOuterContext = this;  
    }  
    ......  
}  

 

Step 4. new ContextImpl

class ContextImpl extends Context {  
    ......  
  
    private Context mOuterContext;  
    ......  
  
    ContextImpl() {  
        // For debug only  
        //++sInstanceCount;  
        mOuterContext = this;  
    }  
    ......  
}  

 

 

Step 5. ContextImpl.setOuterContext

class ContextImpl extends Context {  
    ......  
  
    private Context mOuterContext;  
    ......  
  
    final void setOuterContext(Context context) {  
        mOuterContext = context;  
    }  
  
    ......  
} 

 

Step 6. Activity.attach

public class Activity extends ContextThemeWrapper
        implements LayoutInflater.Factory, Window.Callback, KeyEvent.Callback,
        OnCreateContextMenuListener, ComponentCallbacks {
    ......

    private Application mApplication;
    ......

    /*package*/ Configuration mCurrentConfig;
    ......

    private Window mWindow;

    private WindowManager mWindowManager;
    ......

    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,
            Object lastNonConfigurationInstance,
            HashMap<String,Object> lastNonConfigurationChildInstances,
            Configuration config) {
                
        attachBaseContext(context);

        mWindow = PolicyManager.makeNewWindow(this);
        mWindow.setCallback(this);
        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
            mWindow.setSoftInputMode(info.softInputMode);
        }
        ......

        mApplication = application;
        ......

        mWindow.setWindowManager(null, mToken, mComponent.flattenToString());
        ......

        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    }
    ......
}

 

Step 7. ContextThemeWrapper.attachBaseConext

public class ContextThemeWrapper extends ContextWrapper {  
    private Context mBase;  
    ......  
  
    @Override 
    protected void attachBaseContext(Context newBase) {  
        super.attachBaseContext(newBase);  
        mBase = newBase;  
    }  
    ......  
}

 

Step 8. ContextWrapper.attachBaseConext

public class ContextWrapper extends Context {  
    Context mBase;  
    ......  
  
    protected void attachBaseContext(Context base) {  
        if (mBase != null) {  
            throw new IllegalStateException("Base context already set");  
        }  
        mBase = base;  
    }  
  
    ......  
}

 

Step 9. Instrumentation.callActivityOnCreate

public class Instrumentation {  
    ......  
  
    public void callActivityOnCreate(Activity activity, Bundle icicle) {  
        ......  
  
        activity.onCreate(icicle);  
  
        ......  
    }  
    ......  
}

 

Step 10. Activity.onCreate

public class Activity extends ContextThemeWrapper  
        implements LayoutInflater.Factory,  
        Window.Callback, KeyEvent.Callback,  
        OnCreateContextMenuListener, ComponentCallbacks {  
    ......  
  
    boolean mCalled;  
    ......  
  
    /*package*/ boolean mVisibleFromClient = true;  
    ......      
  
    protected void onCreate(Bundle savedInstanceState) {  
        mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(  
                com.android.internal.R.styleable.Window_windowNoDisplay, false);  
        mCalled = true;  
    }  
   
    ......  
}

 

 

At this point, the process of creating an Activity components, as well as the creation of its operating context, it is analysis is complete. This process is relatively simple, we derive information on the following three points:

  1. A running context Android application window is to use a ContextImpl object described in this ContextImpl objects stored respectively in the parent class ContextThemeWrapper Activity class and member variables mBase ContextWrapper, i.e. member variables ContextThemeWrapper classes and ContextWrapper class Mbase directed It is a ContextImpl object.
  2. Activity component in the creation process, that is, when its members attach function is called, will create a PhoneWindow object and is stored in the member variable mWindow used to describe a specific Android application window.
  3. Activity in the last assembly, that member function onCreate its subclasses in the rewritten, it will call the parent class member functions setContentView Activity to create an Android application window views created.

 

Context creation of Service Analysis

ActivityThread.handleCreateService

private void handleCreateService(CreateServiceData data) {
    ...
    Service service = null;
    try {
        java.lang.ClassLoader cl = packageInfo.getClassLoader();
        service = (Service) cl.loadClass(data.info.name).newInstance();
    } catch (Exception e) {
        if (!mInstrumentation.onException(service, e)) {
            throw new RuntimeException(
                "Unable to instantiate service " + data.info.name
                + ": " + e.toString(), e);
        }
    }

    try {
        ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
        context.setOuterContext(service);

        Application app = packageInfo.makeApplication(false, mInstrumentation);
        service.attach(context, this, data.info.name, data.token, app, ActivityManagerNative.getDefault());
        service.onCreate();
        mServices.put(data.token, service);
        try {
            ActivityManagerNative.getDefault().serviceDoneExecuting(
                    data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
        } catch (RemoteException e) {
            // nothing to do.
        }
    } catch (Exception e) {
        if (!mInstrumentation.onException(service, e)) {
            throw new RuntimeException(
                "Unable to create service " + data.info.name
                + ": " + e.toString(), e);
        }
    }
}  

Service.attatch

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;
}

 

 

As can be seen the process of creating context of service and activity is very similar.

 

 

 

Application of the process of creating Context

ActivityThread.handleBindApplication
LoadedApk.makeApplication
    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
    appContext.setOuterContext(app);

Instrumentation.newApplication(Class<?> clazz, Context context)
    Application app = (Application)clazz.newInstance();
    app.attach(context);
    
Application.attach
final void attach(Context context) {
    attachBaseContext(context);
    mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

ContextWrapper.attachBaseContext
    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }

 

Guess you like

Origin www.cnblogs.com/muouren/p/11704777.html