是否有一种方法来获得静态方法内的当前上下文实例?
我正在寻找这种方式,因为我讨厌保存'Context'实例每次它改变。
是否有一种方法来获得静态方法内的当前上下文实例?
我正在寻找这种方式,因为我讨厌保存'Context'实例每次它改变。
当前回答
如果你出于某种原因想在任何类中都有Application上下文,而不仅仅是那些扩展应用程序/活动,也许是一些工厂类或帮助类。你可以将以下单例添加到你的应用程序中。
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;
}
}
然后在应用程序类的onCreate with中初始化它
GlobalAppContextSingleton.getInstance().initialize(this);
在任何地方通过调用使用它
GlobalAppContextSingleton.getInstance().getApplicationContext()
但是,除了应用程序上下文之外,我不推荐使用这种方法。因为它会导致内存泄漏。
其他回答
如果你愿意使用RoboGuice,你可以将上下文注入到任何你想要的类中。下面是如何使用RoboGuice 2.0(在撰写本文时是beta 4)的一个小示例
import android.content.Context;
import android.os.Build;
import roboguice.inject.ContextSingleton;
import javax.inject.Inject;
@ContextSingleton
public class DataManager {
@Inject
public DataManager(Context context) {
Properties properties = new Properties();
properties.load(context.getResources().getAssets().open("data.properties"));
} catch (IOException e) {
}
}
}
下面是一种从UI线程中的任何地方获取应用程序(它是一个上下文)的未记录的方法。它依赖于隐藏的静态方法ActivityThread.currentApplication()。它至少可以在Android 4.x上运行。
try {
final Class<?> activityThreadClass =
Class.forName("android.app.ActivityThread");
final Method method = activityThreadClass.getMethod("currentApplication");
return (Application) method.invoke(null, (Object[]) null);
} catch (final ClassNotFoundException e) {
// handle exception
} catch (final NoSuchMethodException e) {
// handle exception
} catch (final IllegalArgumentException e) {
// handle exception
} catch (final IllegalAccessException e) {
// handle exception
} catch (final InvocationTargetException e) {
// handle exception
}
注意,这个方法有可能返回null,例如,当你在UI线程之外调用这个方法时,或者应用程序没有绑定到线程上。
如果可以更改应用程序代码,使用@RohitGhatol的解决方案仍然更好。
如果你不想修改清单文件,你可以手动将上下文存储在初始活动的静态变量中:
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
}
注意:与所有其他答案一样,这是一个潜在的内存泄漏。
我刚刚发布了一个基于jquery的Android框架,名为Vapor API,旨在简化应用开发。
中心$ facade类维护了一个WeakReference(链接到Ethan Nicholas关于此的出色Java博客文章)到当前Activity上下文,您可以通过调用:
$.act()
WeakReference在不阻止垃圾回收回收原始对象的情况下维护引用,因此不应该存在内存泄漏问题。
当然,缺点是您要承担$.act()可能返回null的风险。我还没有遇到过这种情况,所以这可能只是一个最小的风险,值得一提。
如果你不使用VaporActivity作为你的Activity类,你也可以手动设置上下文:
$.act(Activity);
此外,许多Vapor API框架固有地使用这种存储上下文,这可能意味着如果您决定使用该框架,您根本不需要自己存储它。请查看该网站以获取更多信息和示例。
我希望这对你有所帮助:)
我认为你需要一个getAppContext()方法的主体:
public static Context getAppContext()
return MyApplication.context;