An article so that you completely understand what Context in the end is still not know how to do Android development?

Foreword

Today we analyze the Context of the source code, in the development of APP, we will often use Context, Context then what is it? Its general semantics is "context" then the "context" in the end what is it? By analyzing the source code, we can have a basic understanding of this Context.

Class inheritance graph

We look at the class inheritance graph on Context, we learn by looking at the source code, Context is an abstract class, so it certainly has its implementation class, review its implementation class that is ContextWrapper and ContextImpl, so it's inheritance graph follows :

An article so that you completely understand what Context in the end is still not know how to do Android development?

Context class more concise definition of inheritance, can be learned, Application, Service, Activity Context class are inherited, so from here we can see that:

Context 数量 = Activity 数量 + Service 数量 + 1

In addition, we can see the Application and Service are directly inherited ContextWrapper while Activity is inherited ContextThemeWrapper, this is why? In fact ContextThemeWrapper is on the subject class, Activity is the interface, and Application and Service did not. Next we come to a detailed look at their source code implementation.

ContextWrapper

We enter into ContextWrapper source can be found, it is actually called mBase inside the method, and mBase fact ContextImpl, so eventually have to call its implementation class ContextImpl class inside the method.

public class ContextWrapper extends Context {
    Context mBase;
    public ContextWrapper(Context base) {
        mBase = base;
    }
    protected void attachBaseContext(Context base) {
        if (mBase != null) {
            throw new IllegalStateException("Base context already set");
        }
        mBase = base;
    }
    //其余的都是覆盖Context里面的方法
}

We can follow the above class inheritance graph analysis followed by the above method may actually know ContextWrapper call ContextImpl inside, so Application and Service Activity as well as they should be related to ContextImpl related. In the end it is not the case? We track the source code analysis.

Application

The main method similar to Java programs start, Android has a similar way to that in ActivityThread class also has a main, this is the place to start, we were a little bit track from here:

ActivityThread#main

      //省略部分代码...
      Looper.prepareMainLooper();
      ActivityThread thread = new ActivityThread();
      thread.attach(false);
      //省略部分代码...
      Looper.loop();      
      //省略部分代码...

We find the main method ActivityThread, regardless of the code is omitted, the main method is to constantly get messages from the message queue, and then processed. We do not analyze this stuff Looper associated only with Context analysis of the content, continue to enter attach method,

Android source code analysis, not a plunge, we should analyze its main processes.

ActivityThread#attach

//省略部分代码...
                mInstrumentation = new Instrumentation();
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                //Application的实例创建
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);

                //调用Application里面的生命周期方法onCreate
                mInitialApplication.onCreate();
//省略部分代码...

There appeared ContextImpl, so the following should be something to do with the Application, so the process continues into makeApplication to track down,

LoadedApk#makeApplication

//省略部分代码...
  Application app = null;
 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
//省略部分代码...

Eventually, into which Instrumentation # newApplication method

Instrumentation#newApplication

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

Application#attach

    /**
    * @hide
    */
   /* package */ 
   final void attach(Context context) {
       attachBaseContext(context);
       mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
   }

Come out here very clear, and finally calls attachBaseContext method of ContextWrapper. From the above here, as expected, the analysis here, remember how much? Application is not only know which eventually calls attachBaseContext this method? In this case on the right, the code can not be plunged headlong into the ocean, travel around, that would be disoriented, Android source code so much, so much, one by one detail fundamental analysis is unlikely, we can only grasp the process, then re-targeted analysis of the implementation process. Service-related method which then analyzes.

Service

For Service, we ActivityThread can be found there is a method called handleCreateService, and there are links between the Service and on the ContextImpl.

ActivityThread#handleCreateService

Service service = null;
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,
                   ActivityManager.getService());
           service.onCreate();

For the Application of the code that we can find both, and the like, we attach method into the code view, find

/**
    * @hide
    */
   public final void attach(
           Context context,
           ActivityThread thread, String className, IBinder token,
           Application application, Object activityManager) {
    //调用attachBaseContext方法
       attachBaseContext(context);
       mThread = thread;           // NOTE:  unused - remove?
       mClassName = className;
       mToken = token;
       mApplication = application;
       mActivityManager = (IActivityManager)activityManager;
       mStartCompatibility = getApplicationInfo().targetSdkVersion
               < Build.VERSION_CODES.ECLAIR;
   }

Code is very simple, that's it have anything to do with ContextImpl. Because the Service and Application of ContextWrapper class are inherited, then we have to analyze the code on Activity of.

Activity

Here explain why the Service and Application are inherited ContextWrapper Activity class and is inherited ContextThemeWrapper That is because the Activity is displayed with an interface, and Service and Application did not, so we can see the information ContextThemeWrapper contains themes from name while ContextThemeWrapper but is inherited from ContextWrapper, ContextThemeWrapper source code analysis we can see, there are basically about the theme of the method, but it also covers attachBaseContext method.

We also found it enters Activity Code also attach a similar method and Service

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,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback) {
        //省略部分代码...
        attachBaseContext(context);

Next we analyze Activity and where this have anything to do.

ActivityThread#performLaunchActivity

performLaunchActivity This method is actually starting method Activity, we later come to learn about the content of this method, it analyzes the content of Context. We enter into this method View:

//省略部分代码...
ContextImpl appContext = createBaseContextForActivity(r);
Activity activity = null;
//省略部分代码...
  activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback);
//省略部分代码...

First create ContextImpl by createBaseContextForActivity method then immediately Activity attach inside. So far, about Application, Service and Activity Context source on the base on the same subject. Next we come to solve some practical content.

Examples of understanding

Since Application, Service and Activity Context So in the end there any difference between them? Meanwhile getApplicationContext and getApplication (), what difference does it make? Next we verify through code.

Our current projects are generally custom Application class some initialization operation, in this case also create a new class that inherits from Application MyApplication, and then registered in Manifest.xml, the code is as follows:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("androidos_analysis", "getApplicationContext()——> " + getApplicationContext());
        Log.d("androidos_analysis", "getBaseContext()       ——> " + getBaseContext());
    }
}

Print results are as follows:

getApplicationContext()——> com.ihidea.androidosanalysis.MyApp@9831cf9
getBaseContext()       ——> android.app.ContextImpl@13d643e

We found that when we get through getApplicationContext We affirm that the Application instance, and by getBaseContext acquired is ContextImpl Why is this? We see their realization find

ContextWrapper#getBaseContext

/**
   * @return the base context as set by the constructor or setBaseContext
   */
  public Context getBaseContext() {
      return mBase;
  }

In fact, we have analyzed above their source, we know that in fact this is ContextImpl the mBase. The getApplicationContext

ContextWrapper#getApplicationContext

@Override
  public Context getApplicationContext() {
      return mBase.getApplicationContext();
  }

Through the above analysis, we know that in fact it is itself an Application Context So, this is its own who returned the. So here for getApplicationContext () Examples The result is the MyApplication itself.

Sometimes we will have usage of code inside getApplication, then this with getApplicationContext what difference does it make? We come to know about the log.

We create a MainActivity then print two lines of code in it:

MainActivity#onCreate

Log.d("androidos_analysis", "getApplicationContext()——> " + getApplicationContext());
Log.d("androidos_analysis", "getApplication()       ——> " + getApplication());

An article so that you completely understand what Context in the end is still not know how to do Android development?

We can find these two results returned are the same, it is not difficult to understand,

Activity#getApplication

/** Return the application that owns this activity. */
   public final Application getApplication() {
       return mApplication;
   }

In fact, it is the Application getApplication return of the two are the same. But all returned Application, Android why the existence of these two methods? This involves the scope of the problem, we can find ways of using getApplication scoped Activity and Service, but we can not use this method elsewhere, in which case we can use to get the Application of getApplicationContext. Under what circumstances do? For example: BroadcastReceiver we want to get in the Receiver Application examples we can to get this way:

public class MyReceiver extends BroadcastReceiver {  
    @Override  
    public void onReceive(Context context, Intent intent) { 
        MyApplication myApp = (MyApplication) context.getApplicationContext();  
        //...
    }  
}

The above content is part of the contents on the Context.

Finally, for programmers, content knowledge to learn, there are too many technical, environmental order not to be eliminated only improve ourselves, always us to adapt to the environment, not the environment to adapt to us!

Here attached the above-mentioned technical system diagram related to dozens of sets of Tencent, headlines, Ali, the US group and other companies face questions 19 years , the technology has become a finishing point video and PDF (in fact, spend a lot of time than expected) including knowledge context + many details , because of space limitations, here in the form of pictures to show you part of it.

I believe it will bring you a lot of harvest:

An article so that you completely understand what Context in the end is still not know how to do Android development?

[HD brain diagram above], and [supporting] PDF technology architecture can add me wx: X1524478394 free access

When programmers easily, when a good programmer is a need to learn from junior programmer to senior programmer, architect from primary to senior architect, or to management, technical director from technical manager to each stage We need to have different capabilities. Early to determine their career direction, in order to throw off their peers at work and in capacity building.

Guess you like

Origin blog.51cto.com/14332859/2455749