传递`Context`到处都是混乱的 - 创建类来处理与上下文的不同交互?

CL2*_*L22 7 java android android-context

有很多问题需要处理Context,使用哪些上下文以及如何存储它等等.但每次我将它传递给一个对象,或者创建一个提供访问权限的静态或单例时,我都会觉得很脏.我不确定我得到了什么味道,但它肯定闻起来.

我认为另一种方法是创建充当上下文代理的类,而不是传递给上下文,它将上下文的特性的子集定义为一种接口(不是语言interface关键字).

替代方案的示例(为了便于阅读,省略了代码):

// 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
    }
}
Run Code Online (Sandbox Code Playgroud)

是否存在任何与此相反的OOP原则?还是闻起来有气味?我只是无法决定.

nha*_*man 3

每当将Context实例传递给另一个类时,请思考,

有没有可能这个班级实际上会比Context我传给它的班级活得更久?

如果答案是否定的,请不要担心。如果答案是肯定的,请思考为什么

View例如,正常使用时,永远不会比您的Activity. 一旦Activity垃圾被收集,你的意志View也会被垃圾收集,所以没有什么可担心的。

然而,单身人士的寿命确实更长,并且泄漏Context. 也就是说,当Activity应该被垃圾收集时,它不会被垃圾收集,因为单例仍然有对它的引用。

我想到了几个解决方案:

  • 用于getApplicationContext()单身人士。Context只要你的应用程序存在,这种类型就会存在——因此,只要你的单例存在,它就会存在。
  • 使用WeakReferences。这可以确保您不会保留对您的的主动引用Context,并避免泄漏。但是,您需要补偿Context.

显然,您需要了解垃圾收集的基础知识。这是一篇关于此的文章


至于您给出的示例代码,我认为传递此实例与传递实际Context实例没有什么区别。在这两种情况下,您都持有对Context. 事实上,该类StateStorer似乎是一个单例,并且 - 就像您所做的那样 - 应该提供ApplicationContext.

您还会经常看到,单例在提供 a 时Context,会getApplicationContext()自行调用它以避免此类错误:

public static MySingleton getInstance(final Context context) {
    if(sInstance == null) {
        sInstance = new MySingleton(context.getApplicationContext());
    }

    return sInstance;
}
Run Code Online (Sandbox Code Playgroud)