gpt4 book ai didi

android - volley 请求的匿名监听器导致内存泄漏

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:53:34 25 4
gpt4 key购买 nike

我正在使用 volley 库进行网络服务调用。我做了一个通用类,用于调用所有 Web 服务并从那里调用服务,并为成功和错误响应创建了匿名监听器。

但是当我使用 leak canary 时,它显示与上下文相关的内存泄漏。下面是我的代码 fragment :

public void sendRequest(final int url, final Context context, final ResponseListener responseListener, final Map<String, String> params) {
StringRequest stringRequest;
if (isNetworkAvailable(context)) {

stringRequest = new StringRequest(methodType, actualURL + appendUrl, new Listener<String>() {
@Override
public void onResponse(String response) {
dismissProgressDialog(context);
try {
(responseListener).onResponse(url, response);
} catch (JsonSyntaxException e) {
// Util.showToast(context, context.getResources().getString(R.string.error));
Crashlytics.logException(e);
}
}

}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// Util.showToast(context,context.getString(R.string.error));

dismissProgressDialog(context);
if (error instanceof NetworkError) {
Util.showToast(context, context.getResources().getString(R.string.network_error));
} else if (error instanceof NoConnectionError) {
Util.showToast(context, context.getResources().getString(R.string.server_error));
} else if (error instanceof TimeoutError) {
Util.showToast(context, context.getResources().getString(R.string.timeout_error));
} else {
Util.showToast(context, context.getResources().getString(R.string.default_error));
}


}

}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return params;
}


@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return request.getHeaders(context, actualURL, false);
}
};
stringRequest.setRetryPolicy(new DefaultRetryPolicy(30000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
VolleySingleton.getInstance(context).addRequest(stringRequest);
} else {
Util.showToast(context, context.getString(R.string.internet_error_message));
}
}

我还创建了一个名为响应监听器的接口(interface),用于将响应重定向到 Activity 或 fragment 。我提出如下要求。

Request.getRequest().sendRequest(Request.SOME URL, SplashScreenActivity.this, SplashScreenActivity.this, new HashMap<String, String>());

但我正面临内存泄漏:

In 2.1.1:31.
* activity.SplashScreenActivity has leaked:
* GC ROOT com.android.volley.NetworkDispatcher.<Java Local>
* references network.Request$5.mListener (anonymous subclass of com.android.volley.toolbox.StringRequest)
* references network.Request$3.val$responseListener (anonymous implementation of com.android.volley.Response$Listener)
* leaks activity.SplashScreenActivity instance
* Retaining: 1.2MB.
* Reference Key: b8e318ea-448c-454d-9698-6f2d1afede1e
* Device: samsung samsung SM-G355H kanas3gxx
* Android Version: 4.4.2 API: 19 LeakCanary: 1.4 6b04880
* Durations: watch=5052ms, gc=449ms, heap dump=2617ms, analysis=143058ms

任何消除此泄漏的想法都将受到任何帮助。

最佳答案

通常,匿名类对封闭类实例具有强引用。在您的情况下,这将是 SplashScreenActivity。现在我想,在您通过 Volley 从服务器获得响应之前,您的 Activity 已经完成。由于监听器对封闭 Activity 具有强引用,因此在 Anonymous 类完成之前,无法对 Activity 进行垃圾回收。你应该做的是标记你发送的所有请求与 Activity 实例,并在 Activity 的 onDestroy() 回调中取消所有请求。

stringRequest.setTag(activityInstance);

要取消所有待处理的请求:

requestQueue.cancellAll(activityInstance);

此外,使用 VolleySingleton 中的应用程序上下文来创建 RequestQueue。

mRequestQueue = Volley.newRequestQueue(applicationContext);

不要在那里使用您的 Activity 上下文,也不要在 VolleySingleton 中缓存您的 Activity 实例。

关于android - volley 请求的匿名监听器导致内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39630712/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com