Static way to get 'Context' in Android?

前端 未结 19 2724
猫巷女王i
猫巷女王i 2020-11-21 06:36

Is there a way to get the current Context instance inside a static method?

I\'m looking for that way because I hate saving the \'Context\' instance eac

相关标签:
19条回答
  • 2020-11-21 07:13

    It depends on what you are using the context for. I can think of at least one disadvantage to that method:

    If you are trying to create an AlertDialog with AlertDialog.Builder, the Application context won't work. I believe you need the context for the current Activity...

    0 讨论(0)
  • 2020-11-21 07:13

    If you for some reason want Application context in any class, not just those extending application/activity, maybe for some factory or helper classes. You can add the following singleton to your app.

    public class GlobalAppContextSingleton {
        private static GlobalAppContextSingleton mInstance;
        private Context context;
    
        public static GlobalAppContextSingleton getInstance() {
            if (mInstance == null) mInstance = getSync();
            return mInstance;
        }
    
        private static synchronized GlobalAppContextSingleton getSync() {
            if (mInstance == null) mInstance = 
                    new GlobalAppContextSingleton();
            return mInstance;
        }
    
        public void initialize(Context context) {
            this.context = context;
        }
    
        public Context getApplicationContext() {
            return context;
        }
    }
    

    then initialize it in your application class's onCreate with

    GlobalAppContextSingleton.getInstance().initialize(this);
    

    use it anywhere by calling

    GlobalAppContextSingleton.getInstance().getApplicationContext()
    

    I don't recommend this approach to anything but application context however. As it can cause memory leaks.

    0 讨论(0)
  • 2020-11-21 07:16

    Do this:

    In the Android Manifest file, declare the following.

    <application android:name="com.xyz.MyApplication">
    
    </application>
    

    Then write the class:

    public class MyApplication extends Application {
    
        private static Context context;
    
        public void onCreate() {
            super.onCreate();
            MyApplication.context = getApplicationContext();
        }
    
        public static Context getAppContext() {
            return MyApplication.context;
        }
    }
    

    Now everywhere call MyApplication.getAppContext() to get your application context statically.

    0 讨论(0)
  • 2020-11-21 07:16

    The majority of apps that want a convenient method to get the application context create their own class which extends android.app.Application.

    GUIDE

    You can accomplish this by first creating a class in your project like the following:

    import android.app.Application;
    import android.content.Context;
    
    public class App extends Application {
    
        private static Application sApplication;
    
        public static Application getApplication() {
            return sApplication;
        }
    
        public static Context getContext() {
            return getApplication().getApplicationContext();
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            sApplication = this;
        }
    }
    

    Then, in your AndroidManifest you should specify the name of your class in the AndroidManifest.xml’s tag:

    <application 
        ...
        android:name="com.example.App" >
        ...
    </application>
    

    You can then retrieve the application context in any static method using the following:

    public static void someMethod() {
        Context context = App.getContext();
    }
    

    WARNING

    Before adding something like the above to your project you should consider what the documentation says:

    There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton.


    REFLECTION

    There is also another way to get the application context using reflection. Reflection is often looked down upon in Android and I personally think this should not be used in production.

    To retrieve the application context we must invoke a method on a hidden class (ActivityThread) which has been available since API 1:

    public static Application getApplicationUsingReflection() throws Exception {
        return (Application) Class.forName("android.app.ActivityThread")
                .getMethod("currentApplication").invoke(null, (Object[]) null);
    }
    

    There is one more hidden class (AppGlobals) which provides a way to get the application context in a static way. It gets the context using ActivityThread so there really is no difference between the following method and the one posted above:

    public static Application getApplicationUsingReflection() throws Exception {
        return (Application) Class.forName("android.app.AppGlobals")
                .getMethod("getInitialApplication").invoke(null, (Object[]) null);
    } 
    

    Happy coding!

    0 讨论(0)
  • 2020-11-21 07:17

    According to this source you can obtain your own Context by extending ContextWrapper

    public class SomeClass extends ContextWrapper {
    
        public SomeClass(Context base) {
          super(base);
        }
    
        public void someMethod() {
            // notice how I can use "this" for Context
            // this works because this class has it's own Context just like an Activity or Service
            startActivity(this, SomeRealActivity.class);
    
            //would require context too
            File cacheDir = getCacheDir();
        }
    }
    

    JavaDoc for ContextWrapper

    Proxying implementation of Context that simply delegates all of its calls to another Context. Can be subclassed to modify behavior without changing the original Context.

    0 讨论(0)
  • 2020-11-21 07:21

    No, I don't think there is. Unfortunately, you're stuck calling getApplicationContext() from Activity or one of the other subclasses of Context. Also, this question is somewhat related.

    0 讨论(0)
提交回复
热议问题