是否有一种方法来获得静态方法内的当前上下文实例?
我正在寻找这种方式,因为我讨厌保存'Context'实例每次它改变。
是否有一种方法来获得静态方法内的当前上下文实例?
我正在寻找这种方式,因为我讨厌保存'Context'实例每次它改变。
当前回答
在Kotlin中,将Context/App Context放在同伴对象中仍然会产生警告,不要将Android Context类放在静态字段中;这是一个内存泄漏(也破坏了即时运行)
或者如果你使用这样的东西:
companion object {
lateinit var instance: MyApp
}
这只是愚弄lint不发现内存泄漏,App实例仍然可以产生内存泄漏,因为Application类及其后代是一个Context。
或者,你可以使用功能界面或功能属性来帮助你获得应用上下文。
简单地创建一个对象类:
object CoreHelper {
lateinit var contextGetter: () -> Context
}
或者你可以使用nullable type更安全:
object CoreHelper {
var contextGetter: (() -> Context)? = null
}
在你的App类中添加这一行:
class MyApp: Application() {
override fun onCreate() {
super.onCreate()
CoreHelper.contextGetter = {
this
}
}
}
在你的manifest中声明应用名。MyApp
<application
android:name=".MyApp"
当你想获取上下文时,只需调用:
CoreHelper.contextGetter()
// or if you use the nullable version
CoreHelper.contextGetter?.invoke()
希望能有所帮助。
其他回答
如果你不想修改清单文件,你可以手动将上下文存储在初始活动的静态变量中:
public class App {
private static Context context;
public static void setContext(Context cntxt) {
context = cntxt;
}
public static Context getContext() {
return context;
}
}
当你的activity(或多个activity)开始时,只需设置上下文:
// MainActivity
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set Context
App.setContext(getApplicationContext());
// Other stuff
}
注意:与所有其他答案一样,这是一个潜在的内存泄漏。
不,我想没有。不幸的是,您只能从Activity或Context的其他子类调用getApplicationContext()。而且,这个问题有点相关。
我使用单例设计模式的一个变体来帮助我做到这一点。
import android.app.Activity;
import android.content.Context;
public class ApplicationContextSingleton {
private static Activity gContext;
public static void setContext( Activity activity) {
gContext = activity;
}
public static Activity getActivity() {
return gContext;
}
public static Context getContext() {
return gContext;
}
}
然后调用ApplicationContextSingleton。setContext(this);在我的activity.onCreate()和ApplicationContextSingleton。setContext(null);在onDestroy ();
大多数想要一个方便的方法来获取应用上下文的应用程序都会创建自己的类来扩展android.app.Application。
指南
你可以先在你的项目中创建一个类,如下所示:
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;
}
}
然后,在你的AndroidManifest中,你应该在AndroidManifest.xml的标签中指定你的类名:
<application
...
android:name="com.example.App" >
...
</application>
然后你可以使用以下方法在任何静态方法中检索应用程序上下文:
public static void someMethod() {
Context context = App.getContext();
}
警告
在向你的项目添加上述内容之前,你应该考虑一下文档中的内容:
通常不需要子类化Application。在大多数情况下, 静态单例可以以更模块化的方式提供相同的功能 道路如果你的单例需要一个全局上下文(例如注册 广播接收器),检索它的函数可以给出一个 在内部使用Context. getapplicationcontext()时 首先构造单例。
反射
还有另一种使用反射获取应用程序上下文的方法。在Android中,反射经常被轻视,我个人认为不应该在产品中使用。
要检索应用程序上下文,我们必须调用一个隐藏类(ActivityThread)的方法,该方法从API 1开始就可用:
public static Application getApplicationUsingReflection() throws Exception {
return (Application) Class.forName("android.app.ActivityThread")
.getMethod("currentApplication").invoke(null, (Object[]) null);
}
还有一个隐藏类(AppGlobals),它提供了一种以静态方式获取应用程序上下文的方法。它使用ActivityThread获取上下文,所以下面的方法和上面发布的方法没有区别:
public static Application getApplicationUsingReflection() throws Exception {
return (Application) Class.forName("android.app.AppGlobals")
.getMethod("getInitialApplication").invoke(null, (Object[]) null);
}
编码快乐!
根据这个源代码,您可以通过扩展ContextWrapper来获得自己的Context
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
Context的代理实现,简单地将其所有调用委托给另一个Context。可以通过子类化来修改行为而不改变原始上下文。