使用这种方式将上下文传递给非上下文类是否安全

时间:2015-08-12 10:45:50

标签: java android android-context

我已经阅读了几篇关于将上下文传递给适配器或其他内容的文章,并且我为获取应用程序上下文制作了某种上下文代码:

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());
    }

在其他一些类中,我需要使用contex:

ContextHolder contextHolder = ContextHolder.getInstance();
Resources resources = contextHolder.getApplicationContext().getResources();

问题是,我做对了吗? 它会导致内存泄漏或其他令人讨厌的东西吗?

2 个答案:

答案 0 :(得分:7)

  在MainActivity中

创建ContextHolder

但是为了什么? Activity已成为Context的子类:

java.lang.Object
  ↳ android.content.Context
    ↳ android.content.ContextWrapper
      ↳ android.view.ContextThemeWrapper
        ↳ android.app.Activity

所以你可以使用this(或MainActivity.this)。更不用说contextHolder变量,您将持有者对象放在显示的代码中属于本地范围,仅在onCreate()中可见。

  

它会导致内存泄漏或其他令人讨厌的东西吗?

我建议使用LeakCanary来捕获代码中的所有内存泄漏。请参阅:https://github.com/square/leakcanary

  

在其他一些课程中,我需要使用contex:

ContextHolder contextHolder = ContextHolder.getInstance();
Resources resources = contextHolder.getApplicationContext().getResources();

这一切都是不必要的,也是过度设计的。如果只需要获取应用程序上下文,则继承Application class:

class MyApplication extends Application {
    protected static Context mContext;

    @Override
    public void onCreate() {
       super.onCreate();

       mContext = this;
    }

    public static Context getAppContext() {
       return mContext;
    }
}

在Manifest中将其设置为您的app应用程序类:

<application
    android:name=".MyApplication"
    ...

然后,当你需要上下文时,你无法通过其他方式,只需致电:

MyApplication.getAppContext();

答案 1 :(得分:1)

我认为您持有对应用程序上下文的引用的方法很好。正如docs所说:

  

通常不需要子类Application。在大多数情况下,静态单例可以以更模块化的方式提供相同的功能。

因此,只是为了获取对应用程序上下文的引用,您不应该继承Application类。

在您的情况下,您应该在第一个活动的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;
    }
}

在您的第一个活动onCreate

ContextHolder.init(getApplicationContext());