Difference between getContext() , getApplicationContext() , getBaseContext() and “this”

前端 未结 8 1921
臣服心动
臣服心动 2020-11-22 02:15

What is the difference between getContext() , getApplicationContext() , getBaseContext() , and \"this\"?

Though

8条回答
  •  無奈伤痛
    2020-11-22 02:26

    Most answers already cover getContext() and getApplicationContext() but getBaseContext() is rarely explained.

    The method getBaseContext() is only relevant when you have a ContextWrapper. Android provides a ContextWrapper class that is created around an existing Context using:

    ContextWrapper wrapper = new ContextWrapper(context);
    

    The benefit of using a ContextWrapper is that it lets you “modify behavior without changing the original Context”. For example, if you have an activity called myActivity then can create a View with a different theme than myActivity:

    ContextWrapper customTheme = new ContextWrapper(myActivity) {
      @Override
      public Resources.Theme getTheme() { 
        return someTheme;
      }
    }
    View myView = new MyView(customTheme);
    

    ContextWrapper is really powerful because it lets you override most functions provided by Context including code to access resources (e.g. openFileInput(), getString()), interact with other components (e.g. sendBroadcast(), registerReceiver()), requests permissions (e.g. checkCallingOrSelfPermission()) and resolving file system locations (e.g. getFilesDir()). ContextWrapper is really useful to work around device/version specific problems or to apply one-off customizations to components such as Views that require a context.

    The method getBaseContext() can be used to access the “base” Context that the ContextWrapper wraps around. You might need to access the “base” context if you need to, for example, check whether it’s a Service, Activity or Application:

    public class CustomToast {
      public void makeText(Context context, int resId, int duration) {
        while (context instanceof ContextWrapper) {
          context = context.baseContext();
        }
        if (context instanceof Service)) {
          throw new RuntimeException("Cannot call this from a service");
        }
        ...
      }
    }
    

    Or if you need to call the “unwrapped” version of a method:

    class MyCustomWrapper extends ContextWrapper {
      @Override
      public Drawable getWallpaper() {
        if (BuildInfo.DEBUG) {
          return mDebugBackground;
        } else {
          return getBaseContext().getWallpaper();
        }
      }
    }
    

提交回复
热议问题