在上下文无效后使用通过android上下文获得的对象

在上下文无效后使用通过android上下文获得的对象,android,garbage-collection,thread-safety,android-context,Android,Garbage Collection,Thread Safety,Android Context,我使用android已经有一段时间了,对这个平台感觉很舒服,但我对上下文对象的生命周期有点困惑。从层次结构上看,很容易看出活动和服务都扩展了上下文,虽然这很方便,但也很重要。我避免了让需要共享资源的助手类有一个保存上下文的静态字段(因为几乎所有的资源都是通过与上下文对象的一些交互实现的),这样当一个活动被销毁时,GC可以随时释放它,但我想知道从上下文获取的资源 例如,如果我有一个静态字段,它在类中保存一个文件。然后让这个类的构造函数获取当前的上下文,并为该文件分配一个通过传入的上下文获取的文件资

我使用android已经有一段时间了,对这个平台感觉很舒服,但我对上下文对象的生命周期有点困惑。从层次结构上看,很容易看出活动和服务都扩展了上下文,虽然这很方便,但也很重要。我避免了让需要共享资源的助手类有一个保存上下文的静态字段(因为几乎所有的资源都是通过与上下文对象的一些交互实现的),这样当一个活动被销毁时,GC可以随时释放它,但我想知道从上下文获取的资源

例如,如果我有一个静态字段,它在类中保存一个文件。然后让这个类的构造函数获取当前的上下文,并为该文件分配一个通过传入的上下文获取的文件资源,在我的第二个类中对上下文不做任何其他事情,我是否仍然以某种方式保持上下文

class testClass{
    private static File someFile;
    public testClass(Context context){
        synchronized(testClass.class){
            if(someFile!=null){
                //even though I am holding a File, or a SharedPreference Object generated from this context, am I correctly preventing this utility class from holding the Activity object in memory for no reason?
                someFile = context.openFileOutput("Some_File.txt", Context.MODE_PRIVATE);
            }
        }
    }
}

我刚刚读过Context.getApplicationContext()(遗憾的是不是静态的)。它说它返回一个与流程相关的上下文,而不是与活动相关的上下文,所以如果需要保留上下文,请使用该上下文。但是上面的问题仍然存在。

我记得我问过这个问题,我想我会回答的

虽然可能有更多种类的上下文,但开发人员使用的主要上下文是活动上下文和应用程序上下文(以及服务上下文等其他内容)。活动上下文是随活动一起创建和销毁的,因此将其用作活动创建和销毁之间存储的常量引用不是一个好主意。应用程序上下文没有活动上下文所具有的某些内容,但是您希望静态上下文引用的所有内容都存在(文件IO、首选项…)。应用程序上下文也随应用程序一起创建和销毁,因此您可以保证只要应用程序代码正在运行,上下文就有效

因此,应用程序上下文应该用于工作线程之类的事情,这些工作线程可能需要对上下文的常量访问点,但不需要对活动的访问。我学到的最好的方法就是扩展android应用程序类。这个类是在内存中创建应用程序时创建的,只要调用applicationoncreate方法,应用程序上下文就有效。这意味着您可以在自定义应用程序类中创建一个静态函数,用于访问上下文

public class CustomApplication extends Application {
private static Context context;

public void onCreate() {
    super.onCreate();
    context = getApplicationContext();
}

public Context getAppContext() {
    return context;
};
}
您需要做的另一件事是修改清单文件,以便android知道使用您的应用程序类而不是默认类

<application
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:name=".CustomApplication" >