"警告:不要将Android上下文类放在静态字段中;这是内存泄漏(并且还会中断Instant Run)"

X09*_*X09 14 java android memory-leaks android-volley

类似的问题已经被问这里,这里这里,但背景是从这个完全不同,而且,从这个错误给代码是由Android和Android工作室的制作者编写的.

这是代码:

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

发出警告的行是:

private static MySingleton mInstance;
private static Context mCtx;
Run Code Online (Sandbox Code Playgroud)

现在,如果我删除static关键字,请更改public static synchronized MySingleton getInstance(Context...public synchronized MySingleton getInstance(Context...错误消息,但会出现另一个问题.

MySingleton在RecyclerView中使用.所以这一行

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

告诉我

无法从静态上下文中引用非静态方法'getInstance(android.content.Context)'.

请有人知道如何解决这个问题?

X09*_*X09 17

我在CommonsWare回答的类似问题答案中找到了解决方案

我引用

引用的Lint警告并没有抱怨创建单身人士.它抱怨创建单个控件,其中包含对任意上下文的引用,因为它可能类似于Activity.希望通过将mContext = context更改为mContext = context.getApplicationContext(),您将摆脱该警告(尽管有可能这仍然会破坏Instant Run - 我无法对此发表评论).

创建单例是好的,只要你非常小心地这样做,以避免内存泄漏(例如,持有对Activity的无限静态引用).

因此谷歌实际上并没有签约.要解决这个问题,if if this.getApplicationContext作为上下文的参数提供,那么就不会有内存泄漏.

因此,实质上,忽略警告和供应this.getApplicationContext作为上下文的参数.

  • 我已经有`mContext = context.getApplicationContext()`警告仍然存在! (7认同)
  • 我可以确认,这不会删除lint警告.我不认为更改Context到getApplicationContext将起作用,因为它仍然返回Context类型的对象. (3认同)