使用这种方式将上下文传递给非上下文是否安全类
Is it safe to use this way to pass context to non-context classes
我已经阅读了几篇关于将上下文传递给适配器或其他东西的文章,并且我制作了某种上下文持有者来获取应用程序上下文:
import android.content.Context;
public class ContextHolder {
private static ContextHolder ourInstance = new ContextHolder();
private Context context;
public static ContextHolder getInstance() {
return ourInstance;
}
private ContextHolder() {
context = null;
}
public void setContext(Context context){
this.context = context;
}
public Context getApplicationContext(){
return context;
}
}
然后在 MainActivity 中创建 ContextHolder 对象并像这样设置上下文:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ContextHolder contextHolder = ContextHolder.getInstance();
contextHolder.setContext(this.getApplicationContext());
}
在其他一些 class 中,我需要使用 contex:
ContextHolder contextHolder = ContextHolder.getInstance();
Resources resources = contextHolder.getApplicationContext().getResources();
问题是,我做的对吗?
它会导致内存泄漏或其他讨厌的东西吗?
in MainActivity i`m creating ContextHolder
但是为了什么? Activity 已经是上下文的子class:
java.lang.Object
↳ android.content.Context
↳ android.content.ContextWrapper
↳ android.view.ContextThemeWrapper
↳ android.app.Activity
所以您可以只使用 this
(或 MainActivity.this
)。更不用说 contextHolder
变量,你把你的 holder 对象放在显示的代码中是局部范围的,并且只在 onCreate()
中可见。
Can it cause memory leaks or other nasty stuff?
我建议使用 LeakCanary 来捕获代码中的所有内存泄漏。参见:https://github.com/square/leakcanary
In some other class, where i need to use contex:
ContextHolder contextHolder = ContextHolder.getInstance();
Resources resources = contextHolder.getApplicationContext().getResources();
这都是不必要的,而且设计过度了。如果你只需要获取应用程序上下文,subclass Application
class:
class MyApplication extends Application {
protected static Context mContext;
@Override
public void onCreate() {
super.onCreate();
mContext = this;
}
public static Context getAppContext() {
return mContext;
}
}
在清单中将其设置为您的应用程序 class:
<application
android:name=".MyApplication"
...
然后,每当您需要无法通过其他方式获得的上下文时,只需调用:
MyApplication.getAppContext();
我认为您保存对应用程序上下文的引用的方法很好。正如 docs 所说:
There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way.
因此,仅仅为了获取对您的应用程序上下文的引用,您不应该 class 应用程序 class。
在您的情况下,您应该在第一个 activity 的 onCreate
方法中初始化您的单例,以便您应该将 this.getApplicationContext()
传递给您的单例以保持。例如:
public class ContextHolder {
private static ContextHolder ourInstance;
private Context context;
public static ContextHolder getInstance() {
return ourInstance;
}
public static void init(Context context){
ourInstance = new ContextHolder(context);
}
private ContextHolder(Context context) {
this.context = context;
}
public Context getApplicationContext(){
return context;
}
}
在你的第一个 Activity 中 onCreate
:
ContextHolder.init(getApplicationContext());
我已经阅读了几篇关于将上下文传递给适配器或其他东西的文章,并且我制作了某种上下文持有者来获取应用程序上下文:
import android.content.Context;
public class ContextHolder {
private static ContextHolder ourInstance = new ContextHolder();
private Context context;
public static ContextHolder getInstance() {
return ourInstance;
}
private ContextHolder() {
context = null;
}
public void setContext(Context context){
this.context = context;
}
public Context getApplicationContext(){
return context;
}
}
然后在 MainActivity 中创建 ContextHolder 对象并像这样设置上下文:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ContextHolder contextHolder = ContextHolder.getInstance();
contextHolder.setContext(this.getApplicationContext());
}
在其他一些 class 中,我需要使用 contex:
ContextHolder contextHolder = ContextHolder.getInstance();
Resources resources = contextHolder.getApplicationContext().getResources();
问题是,我做的对吗? 它会导致内存泄漏或其他讨厌的东西吗?
in MainActivity i`m creating ContextHolder
但是为了什么? Activity 已经是上下文的子class:
java.lang.Object
↳ android.content.Context
↳ android.content.ContextWrapper
↳ android.view.ContextThemeWrapper
↳ android.app.Activity
所以您可以只使用 this
(或 MainActivity.this
)。更不用说 contextHolder
变量,你把你的 holder 对象放在显示的代码中是局部范围的,并且只在 onCreate()
中可见。
Can it cause memory leaks or other nasty stuff?
我建议使用 LeakCanary 来捕获代码中的所有内存泄漏。参见:https://github.com/square/leakcanary
In some other class, where i need to use contex:
ContextHolder contextHolder = ContextHolder.getInstance();
Resources resources = contextHolder.getApplicationContext().getResources();
这都是不必要的,而且设计过度了。如果你只需要获取应用程序上下文,subclass Application
class:
class MyApplication extends Application {
protected static Context mContext;
@Override
public void onCreate() {
super.onCreate();
mContext = this;
}
public static Context getAppContext() {
return mContext;
}
}
在清单中将其设置为您的应用程序 class:
<application
android:name=".MyApplication"
...
然后,每当您需要无法通过其他方式获得的上下文时,只需调用:
MyApplication.getAppContext();
我认为您保存对应用程序上下文的引用的方法很好。正如 docs 所说:
There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way.
因此,仅仅为了获取对您的应用程序上下文的引用,您不应该 class 应用程序 class。
在您的情况下,您应该在第一个 activity 的 onCreate
方法中初始化您的单例,以便您应该将 this.getApplicationContext()
传递给您的单例以保持。例如:
public class ContextHolder {
private static ContextHolder ourInstance;
private Context context;
public static ContextHolder getInstance() {
return ourInstance;
}
public static void init(Context context){
ourInstance = new ContextHolder(context);
}
private ContextHolder(Context context) {
this.context = context;
}
public Context getApplicationContext(){
return context;
}
}
在你的第一个 Activity 中 onCreate
:
ContextHolder.init(getApplicationContext());