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

Noo*_*kie 3 java android android-context

我已经阅读了几篇关于将上下文传递给适配器或其他内容的文章,并且我为获取应用程序上下文做了一些contextholder:

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

然后在MainActivity中创建ContextHolder对象并设置上下文,如下所示:

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ContextHolder contextHolder = ContextHolder.getInstance();
        contextHolder.setContext(this.getApplicationContext());
    }
Run Code Online (Sandbox Code Playgroud)

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

ContextHolder contextHolder = ContextHolder.getInstance();
Resources resources = contextHolder.getApplicationContext().getResources();
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ski 7

在MainActivity我创建ContextHolder

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

java.lang.Object
  ? android.content.Context
    ? android.content.ContextWrapper
      ? android.view.ContextThemeWrapper
        ? android.app.Activity
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

ContextHolder contextHolder = ContextHolder.getInstance();
Resources resources = contextHolder.getApplicationContext().getResources();
Run Code Online (Sandbox Code Playgroud)

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

class MyApplication extends Application {
    protected static Context mContext;

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

       mContext = this;
    }

    public static Context getAppContext() {
       return mContext;
    }
}
Run Code Online (Sandbox Code Playgroud)

将它设置为Manifest中的app应用程序类:

<application
    android:name=".MyApplication"
    ...
Run Code Online (Sandbox Code Playgroud)

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

MyApplication.getAppContext();
Run Code Online (Sandbox Code Playgroud)