java - "Warning: Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)"

标签 java android memory-leaks android-volley

类似的问题是asked here , herehere但上下文与此完全不同,而且 code that gave from this error由 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();

告诉我

Non-static method 'getInstance(android.content.Context)' cannot be refrenced from a static context.

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

最佳答案

我在 answer to a similar question answered by CommonsWare 中找到了解决方案

我引用

The quoted Lint warning is not complaining about creating singletons. It is complaining about creating singletons holding a reference to an arbitrary Context, as that could be something like an Activity. Hopefully, by changing mContext = context to mContext = context.getApplicationContext(), you will get rid of that warning (though it is possible that this still breaks Instant Run — I cannot really comment on that).

Creating singletons is fine, so long as you do so very carefully, to avoid memory leaks (e.g., holding an indefinite static reference to an Activity).

所以 Google 实际上并没有与自己签约。要解决此问题,如果将 this.getApplicationContext 作为上下文的参数提供,则不会发生内存泄漏。

所以本质上,忽略警告并提供 this.getApplicationContext 作为上下文的参数。

关于java - "Warning: Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40094020/

相关文章:

ruby - 为什么 Ruby 只是偶尔释放内存?

Java 保护网络流量

java - JAVA如何获取上传速度

java - (Android) 通过一个简单的套接字攻击服务器

android - cordova 文件传输插件下载未显示在图片库中

iOS - 由于内存问题而终止

JavaFX 警告 : System can't support ConditionalFeature. SCENE3D

java - 如何重新转换java数组

java - 有没有办法禁用 MotionLayout 可见性更改动画?

memory-leaks - dlopen 中 valgrind 报告的内存泄漏?