到处传递“Context”的java看起来很混乱,是否创建类来处理与上下文的不同交互?
有大量的问题涉及Context
,使用哪种上下文,以及如何存储它,等等。但是每次我将它传递给对象,或者创建一个提供对它的访问的静态或单例时,我都会感到脏兮兮的。我不确定我闻到了什么味道,但它确实有味道
我在想另一种方法是创建充当上下文代理的类,而我将其传递给上下文,将上下文特性的子集定义为一种接口(而不是languageinterface
关键字)
备选方案的一个示例(为便于阅读而省略代码):
// in activity.onCreate():
StateStorer ss = new StateStorer (getApplicationContext());
RememberMe obj = new RememberMe(ss);
ss.restore();
// in activity.onDestroy()
ss.save();
// the "proxy"
class StateStorer {
List<StateStorerListener> listeners;
Context mContext;
public StateStorer(Context context){
mContext = context;
}
public SharedPreferences getSharedPreferences(String tag){
return mContext.getSharedPreferences(tag, 0);
}
public save(){
// tell listeners to save
}
public restore(){
// tell listeners to restore
}
}
// an example class that needs to save state
class RememberMe {
public String TAG = "RememberMe";
public StateStorer mSs;
public RememberMe (StateStorer ss){
mSs = ss;
ss.addListener(this)
}
// this class would implement the StateStorer's listener interface,
// and when the StateStorer tells it to save or restore, it will use the
// StateStorer's methods to access the SharedPreferences object
public void onRestore(){
SharedPreferences sp = sSs.getSharedPreferences(TAG);
// restore from prefs here
}
}
这有什么违反OOP原则的吗?或者它能修复的气味?我就是不能决定
# 1 楼答案
看起来像是整洁的代码。但为什么要经历所有这些复杂的动作,只是为了传递上下文?在我看来,你现在正在传递一个不同的类(你的RememberMe类),这和传递上下文一样好或坏。所以我并不认为这有什么好处
# 2 楼答案
每当将
Context
实例传递给另一个类时,请思考如果答案是否定的,不要担心。如果答案是肯定的,想想为什么
例如
View
在正常使用时,它的寿命永远不会超过你的Activity
。一旦Activity
被收集到垃圾,你的View
就会被收集到垃圾,所以没什么好担心的然而,确实活得更长,将泄漏
Context
。也就是说,当Activity
应该被垃圾收集时,它将不会被垃圾收集,因为singleton仍然有对它的引用我想到了几个解决方案:
getApplicationContext()
。这种类型的Context
的寿命与应用程序的寿命一样长,因此与单例生命一样长李>WeakReference
s。这样可以确保不会保留对Context
的活动引用,并避免泄漏。然而,您需要补偿Context
的可能为空李>显然,您需要了解垃圾收集的基本知识Here's an article about that
至于您给出的示例代码,我认为传递这个实例与传递实际的
Context
没有什么区别。在这两种情况下,您都持有对Context
的引用。事实上,StateStorer
类似乎是一个单例,并且-就像您所做的那样-应该提供ApplicationContext
您还会经常看到,当提供
Context
时,单例会自己调用getApplicationContext()
,以避免此类错误: