“警告:不要将Android上下文类放在静态字段中;这是一个内存泄漏(也会破坏即时运行)”

2022-09-02 20:46:53

这里,这里这里过类似的问题,但上下文与此完全不同,而且从此错误中给出的代码是由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;

现在,如果我删除关键字,请更改为错误消除器,但会出现另一个问题。staticpublic 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)'不能从静态上下文中折射。

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


答案 1

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

我引用

引用的Lint警告并不是抱怨创建单例。它抱怨创建单例来保存对任意上下文的引用,因为这可能是类似于活动的东西。希望通过将 mContext = context 更改为 mContext = context.getApplicationContext(),您将摆脱该警告(尽管这仍然可能破坏 Instant Run — 我无法对此进行真正的评论)。

创建单例是可以的,只要您非常小心地这样做,以避免内存泄漏(例如,持有对活动的无限期静态引用)。

因此,谷歌实际上并没有收缩自己。若要解决此问题,如果 作为上下文的参数提供,则不会有内存泄漏。this.getApplicationContext

因此,从本质上讲,忽略警告并作为上下文的参数提供。this.getApplicationContext


答案 2

我最终把它放在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()


推荐