web-dev-qa-db-ja.com

「警告:静的フィールドにAndroidコンテキストクラスを配置しないでください。これはメモリリークです(また、インスタントランを中断します)」」

同様の質問は ここで尋ねたここ 、および ここ でしたが、コンテキストはこれとはまったく異なり、さらに このエラー は、AndroidおよびAndroid Studio。

これはコードです:

_public class MySingleton {
    private static MySingleton mInstance;
    private RequestQueue mRequestQueue;
    private ImageLoader mImageLoader;
    private static Context mCtx;

    private MySingleton(Context context) {
        mCtx = context;
        mRequestQueue = getRequestQueue();

        mImageLoader = new ImageLoader(mRequestQueue,
                new ImageLoader.ImageCache() {
            private final LruCache<String, Bitmap>
                    cache = new LruCache<String, Bitmap>(20);

            @Override
            public Bitmap getBitmap(String url) {
                return cache.get(url);
            }

            @Override
            public void putBitmap(String url, Bitmap bitmap) {
                cache.put(url, bitmap);
            }
        });
    }

    public static synchronized MySingleton getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new MySingleton(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }

    public ImageLoader getImageLoader() {
        return mImageLoader;
    }
}
_

警告を与える行は次のとおりです。

_private static MySingleton mInstance;
private static Context mCtx;
_

staticキーワードを削除した場合、_public static synchronized MySingleton getInstance(Context..._を_public synchronized MySingleton getInstance(Context..._に変更するとエラーが消えますが、別の問題が発生します。

私はRecyclerViewでMySingletonを使用しています。だからこの行

@Override public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) { ImageLoader imageLoader = MySingleton.getInstance(mContext).getImageLoader();

教えて

非静的メソッド「getInstance(Android.content.Context)」は静的コンテキストから参照できません。

誰でもこれを修正する方法を知っていますか?

13
X09

これに対する解決策は CommonsWareが回答した同様の質問への回答 で見つけました。

引用する

引用されたリント警告は、シングルトンの作成について文句を言っていません。任意のコンテキストへの参照を保持するシングルトンを作成することについて文句を言っています。これはアクティビティのようなものになる可能性があるためです。うまくいけば、mContext = contextをmContext = context.getApplicationContext()に変更することで、その警告を取り除くことができます(ただし、これはまだインスタントランを壊す可能性はありますが、実際にコメントすることはできません)。

メモリリーク(アクティビティへの無期限の静的参照を保持するなど)を回避するために、慎重に行う限り、シングルトンの作成は問題ありません。

そのため、Googleは実際には契約していません。これを修正するには、this.getApplicationContextがコンテキストのパラメーターとして提供されるため、メモリリークは発生しません。

したがって、本質的には、警告を無視してthis.getApplicationContextコンテキストのパラメーターとして。

15
X09

私はこれを警告のないAppControllerに入れました。

_public class AppController extends MultiDexApplication {

    public static Context getContext() {
        return mInstance.getApplicationContext();
    }

    private static AppController mInstance;

    public static synchronized AppController getInstance() {
        return mInstance;
    }

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

        mInstance = this;

    }
}
_

必要なときはいつでもAppController.getContext()を呼び出すだけです

4
Arst