Java 截击静态回调侦听器上下文GCed
在使用之后,我发现我的应用程序中有很多漏洞,大多数都是由于截击的匿名回调侦听器造成的。因此我编写了一个Util(如下)类,它使用静态回调和Java 截击静态回调侦听器上下文GCed,java,android,memory-leaks,android-volley,Java,Android,Memory Leaks,Android Volley,在使用之后,我发现我的应用程序中有很多漏洞,大多数都是由于截击的匿名回调侦听器造成的。因此我编写了一个Util(如下)类,它使用静态回调和WeakReference来保持对Context的引用和匿名回调。但是,当我第一次打开应用程序时,即冷启动时,在发出请求后不久就会对上下文进行GCD,但在热启动期间,一切正常。而且,这只会发生在应用程序中的第一个活动中 我们也欢迎使用截击处理内存泄漏的任何其他方法,这些方法可以正常工作 public abstract class VUtil { pu
WeakReference
来保持对Context
的引用和匿名回调。但是,当我第一次打开应用程序时,即冷启动时,在发出请求后不久就会对上下文进行GCD,但在热启动期间,一切正常。而且,这只会发生在应用程序中的第一个活动中
我们也欢迎使用截击处理内存泄漏的任何其他方法,这些方法可以正常工作
public abstract class VUtil {
public static final String TAG = VUtil.class.getSimpleName();
public interface JsonCallback {
void onSuccess(JSONObject response);
}
public interface StringCallback {
void onSuccess(String response);
}
public interface ErrorCallback {
void onError(VolleyError error);
}
public static class JsonResponseListener implements Response.Listener<JSONObject> {
private final WeakReference<Context> mContextWeakReference;
private final WeakReference<JsonCallback> mCallbackWeakReference;
public JsonResponseListener(Context context, JsonCallback callback) {
mContextWeakReference = new WeakReference<>(context);
mCallbackWeakReference = new WeakReference<>(callback);
}
@Override
public void onResponse(JSONObject jsonObject) {
Context context = mContextWeakReference.get();
JsonCallback callback = mCallbackWeakReference.get();
if (context != null && callback != null) {
callback.onSuccess(jsonObject);
} else {
Log.d(TAG, "Context was GCed");
}
}
}
public static class StringResponseListener implements Response.Listener<String> {
private final WeakReference<Context> mContextWeakReference;
private final WeakReference<StringCallback> mCallbackWeakReference;
public StringResponseListener(Context context, StringCallback callback) {
mContextWeakReference = new WeakReference<>(context);
mCallbackWeakReference = new WeakReference<>(callback);
}
@Override
public void onResponse(String response) {
Context context = mContextWeakReference.get();
StringCallback callback = mCallbackWeakReference.get();
if (context != null && callback != null) {
callback.onSuccess(response);
} else {
Log.d(TAG, "Context was GCed");
}
}
}
public static class ErrorListener implements Response.ErrorListener {
private final WeakReference<Context> mContextWeakReference;
private final WeakReference<ErrorCallback> mCallbackWeakReference;
public ErrorListener(Context context, ErrorCallback callback) {
mContextWeakReference = new WeakReference<>(context);
mCallbackWeakReference = new WeakReference<>(callback);
}
@Override
public void onErrorResponse(VolleyError error) {
Context context = mContextWeakReference.get();
ErrorCallback callback = mCallbackWeakReference.get();
if (context != null && callback != null) {
callback.onError(error);
} else {
Log.d(TAG, "Context was GCed");
}
}
}
}
公共抽象类VUtil{
公共静态最终字符串标记=VUtil.class.getSimpleName();
公共接口JsonCallback{
成功时无效(JSONObject响应);
}
公共接口字符串回调{
void onSuccess(字符串响应);
}
公共接口错误回调{
无效错误(截击错误);
}
公共静态类JsonResponseListener实现Response.Listener{
私有最终WeakReference mContextWeakReference;
私人最终WeakReference mCallbackWeakReference;
公共JsonResponseListener(上下文上下文,JsonCallback回调){
mContextWeakReference=新的WeakReference(上下文);
mCallbackWeakReference=新的WeakReference(回调);
}
@凌驾
公共void onResponse(JSONObject JSONObject){
Context Context=mContextWeakReference.get();
JsonCallback callback=mCallbackWeakReference.get();
if(上下文!=null&&callback!=null){
onSuccess(jsonObject);
}否则{
Log.d(标签“上下文为GCed”);
}
}
}
公共静态类StringResponseListener实现Response.Listener{
私有最终WeakReference mContextWeakReference;
私人最终WeakReference mCallbackWeakReference;
公共StringResponseListener(上下文上下文,StringCallback){
mContextWeakReference=新的WeakReference(上下文);
mCallbackWeakReference=新的WeakReference(回调);
}
@凌驾
公共void onResponse(字符串响应){
Context Context=mContextWeakReference.get();
StringCallback callback=mCallbackWeakReference.get();
if(上下文!=null&&callback!=null){
callback.onSuccess(响应);
}否则{
Log.d(标签“上下文为GCed”);
}
}
}
公共静态类ErrorListener实现Response.ErrorListener{
私有最终WeakReference mContextWeakReference;
私人最终WeakReference mCallbackWeakReference;
公共ErrorListener(上下文上下文,ErrorCallback){
mContextWeakReference=新的WeakReference(上下文);
mCallbackWeakReference=新的WeakReference(回调);
}
@凌驾
公共无效onErrorResponse(截击错误){
Context Context=mContextWeakReference.get();
ErrorCallback callback=mCallbackWeakReference.get();
if(上下文!=null&&callback!=null){
callback.onError(错误);
}否则{
Log.d(标签“上下文为GCed”);
}
}
}
}
GC取决于正在发生的许多事情。这种情况的一个可能原因是,当您在“冷启动”后执行第一个请求时,应用程序必须初始化各种自定义对象、片段、活动、视图缓存等,因此在增加堆之前需要内存,从而执行GC
然而,我提出的解决方案是改变您的体系结构
1) 似乎你一直在引用上下文,但它从未被使用过。放下它
2) 您有大量回调,这些回调委托给您需要传递的自定义回调,为什么不使用一组回调传递给相应的请求呢
3) 你有一周的自定义回调,但你不能没有它们。周引用不是内存泄漏的最终解决方案。你必须找出为什么裁判在你不需要的时候还在那里
所以,如果您在JsonCallback中泄漏了问题,StringCallback和ErrorCallback实现只需尝试解决这个问题,而不是使链变长并在最后将其切断。多亏了djodjo的回答,帮助我找到了解决方案
- 始终使用
。这里addToRequestQueue(请求、标记)
bit是当请求的活动/片段/视图或任何内容被GCed时,我们用来取消请求的内容TAG
- 我所做的是创建一个基本活动,并在该活动中添加所有请求取消代码。这是它的样子
从此public abstract class BaseActivity extends AppCompatActivity { public final String tag; public BaseActivity() { super(); tag = getClass().getSimpleName(); } @Override protected void onDestroy() { App.getInstance().cancelRequests(tag); super.onDestroy(); } protected <T> void addToRequestQueue(Request<T> request) { App.getInstance().addToRequestQueue(request, tag); } }
扩展您的活动,并使用BaseActivity
发出请求,当您的活动被销毁时,请求将自动取消。对fragment/dialog/anythis执行类似的操作addToRequestQueue
如果您从任何其他地方发出的请求没有遵循生命周期,请确保它没有绑定到任何上下文
,您会没事的。@Sourabh您如何在Stringrequest中传递该类对象,以及如何从该响应将该响应重定向到相应的activity responsepass对象作为
MyClass。这
?我不明白你所说的
将响应重定向到不同活动的相应活动响应是什么意思,我正在进行网络呼叫,因此无论收到什么响应,我都必须将其重定向到特定活动。@Midslefko,我还想在截击请求中添加cancelAll。我应该在哪里添加“getRequestQueue().cancelAll(tag);”,它是单例模式吗?活动生命周期?我很困惑。非常感谢。将它添加到您的
应用程序
实例中,因为它的Appli
getRequestQueue().cancelAll(tag);