是否有一种方法来获得静态方法内的当前上下文实例?
我正在寻找这种方式,因为我讨厌保存'Context'实例每次它改变。
是否有一种方法来获得静态方法内的当前上下文实例?
我正在寻找这种方式,因为我讨厌保存'Context'实例每次它改变。
当前回答
Assuming we're talking about getting the Application Context, I implemented it as suggested by @Rohit Ghatol extending Application. What happened then, it's that there's no guarantee that the context retrieved in such a way will always be non-null. At the time you need it, it's usually because you want to initialize an helper, or get a resource, that you cannot delay in time; handling the null case will not help you. So I understood I was basically fighting against the Android architecture, as stated in the docs
注意:通常不需要子类化Application。在大多数情况下,静态单例可以以更模块化的方式提供相同的功能。如果你的单例需要一个全局上下文(例如注册广播接收器),在调用你的单例的getInstance()方法时,包括context . getapplicationcontext()作为context参数。
并由黛安·哈克伯恩解释
Application作为派生对象存在的唯一原因是,在1.0之前的开发过程中,我们的一个应用程序开发人员不断地纠缠我,说需要一个顶级的应用程序对象来派生,这样他们就可以有一个更“正常”的应用程序模型,我最终屈服了。 我将永远后悔在这一点上做出了让步。:)
她还提出了这个问题的解决方案:
如果你想要的是一些全局状态,可以在应用程序的不同部分之间共享,请使用单例。[…这就更自然地引出了你应该如何管理这些东西——按需初始化它们。
所以我所做的是摆脱扩展Application,并将上下文直接传递给单例helper的getInstance(),同时在私有构造函数中保存对应用程序上下文的引用:
private static MyHelper instance;
private final Context mContext;
private MyHelper(@NonNull Context context) {
mContext = context.getApplicationContext();
}
public static MyHelper getInstance(@NonNull Context context) {
synchronized(MyHelper.class) {
if (instance == null) {
instance = new MyHelper(context);
}
return instance;
}
}
调用者将传递一个本地上下文给helper:
Helper.getInstance(myCtx).doSomething();
因此,要正确地回答这个问题:有很多方法可以静态地访问应用程序上下文,但都不建议使用,您应该更喜欢将本地上下文传递给单例的getInstance()。
感兴趣的人可以在fwd博客上阅读更详细的版本
其他回答
我刚刚发布了一个基于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;
如果你出于某种原因想在任何类中都有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()
但是,除了应用程序上下文之外,我不推荐使用这种方法。因为它会导致内存泄漏。
我曾经用过这个:
ActivityThread at = ActivityThread.systemMain();
Context context = at.getSystemContext();
这是一个有效的上下文,我用来获得系统服务和工作。
但是,我只在框架/基础修改中使用它,并没有在Android应用程序中尝试它。
你必须知道的一个警告:当用这个上下文注册广播接收器时,它将不起作用,你将得到:
java.lang.SecurityException:给定的调用程序包android没有在进程ProcessRecord中运行
这取决于您使用上下文的目的。我认为这种方法至少有一个缺点:
如果您正在尝试使用AlertDialog创建AlertDialog。Builder,应用程序上下文将无法工作。我相信你需要了解当前活动的背景……