nohttp框架的OnResponseListener内存泄漏问题

fenlyer 2017-06-19 02:17:54
不管回调函数里面写了什么,只要页面跳转,LeakCanary就会弹出来内存泄漏。




求助大神
...全文
279 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
changchengworld 2018-01-12
  • 打赏
  • 举报
回复
对象持有顺序是这样的:你的Activity->ResponseListener->Request->RequestDispatcher,我注意到RequestDispatcher里面有这样一行代码Response<?> response = SyncRequestExecutor.INSTANCE.execute(request); SyncRequestExecutor这个类被做成了一个单例,具体调用链路很长,但是我怀疑也就是它一直间接持有着Request引用导致Request无法释放。当你的Activity关闭的时候,Request对象却无法释放,等于你的ResponseListener无法释放,最终导致你的Activity无法释放。解决方式可以试试看把ResponseListener做成静态内部类,解除对Activity的引用,如果需要在ResponseListener里用到外部类Activity的方法,就把Activity以WeakReference包裹传递进来,这样Activity就能顺利释放了
fenlyer 2017-06-20
  • 打赏
  • 举报
回复
HttpUtils.loginRequest(MD5Tool.md5(name), MD5Tool.md5(password), new OnResponseListener<String>() {

                    @Override
                    public void onStart(int what) {
                    }

                    @Override
                    public void onSucceed(int what, Response<String> response) {

                        //根据返回的数据进行判断,如果是判断出登录失败那么吐司,否则跳转
                        //"wrong".equal(response.getString())
                        if (false) {
                            ToastUtils.show("用户名或者密码错误");
                        } else {
                            String json = response.get();
                            User user = new Gson().fromJson(json, User.class);
                            SharedPreferencesTool.saveString(MyApp.getContext(), Constants.ORGCODE, user.getORG_CODE());
                            SharedPreferencesTool.saveString(MyApp.getContext(), Constants.USERTYPE, user.getUSER_TYPE());
                            SharedPreferencesTool.saveString(MyApp.getContext(), Constants.USERCODE, user.getUSER_CODE());
                            SharedPreferencesTool.saveString(MyApp.getContext(), Constants.USERNAME, user.getUSER_NAME());
                            SharedPreferencesTool.saveString(MyApp.getContext(), Constants.ID, user.getID());
                            Log.e("JSON", json);
                            enterHome();
                        }
                    }

                    @Override
                    public void onFailed(int what, Response<String> response) {
                        ToastUtils.show("登录失败");
                    }

                    @Override
                    public void onFinish(int what) {
                    }
                });
fenlyer 2017-06-20
  • 打赏
  • 举报
回复
HttpUtils.loginRequest(MD5Tool.md5(name), MD5Tool.md5(password), new OnResponseListener<String>() { @Override public void onStart(int what) { } @Override public void onSucceed(int what, Response<String> response) { //根据返回的数据进行判断,如果是判断出登录失败那么吐司,否则跳转 //"wrong".equal(response.getString()) if (false) { ToastUtils.show("用户名或者密码错误"); } else { String json = response.get(); User user = new Gson().fromJson(json, User.class); SharedPreferencesTool.saveString(MyApp.getContext(), Constants.ORGCODE, user.getORG_CODE()); SharedPreferencesTool.saveString(MyApp.getContext(), Constants.USERTYPE, user.getUSER_TYPE()); SharedPreferencesTool.saveString(MyApp.getContext(), Constants.USERCODE, user.getUSER_CODE()); SharedPreferencesTool.saveString(MyApp.getContext(), Constants.USERNAME, user.getUSER_NAME()); SharedPreferencesTool.saveString(MyApp.getContext(), Constants.ID, user.getID()); Log.e("JSON", json); enterHome(); } } @Override public void onFailed(int what, Response<String> response) { ToastUtils.show("登录失败"); } @Override public void onFinish(int what) { } });
清竹_ 2017-06-19
  • 打赏
  • 举报
回复
贴代码啊,LogActivity!
fenlyer 2017-06-19
  • 打赏
  • 举报
回复
NoHttp 是专门做Android网络请求与下载的框架。支持HTTP/HTTPS,自动维持Cookie,异步/同步请求,大文件/多文件上传,文件下载;支持304缓存,302/303重定向,支持代理服务器。NoHttp特性:支持HTTP/HTTPS,自动维持Cookie,异步/同步请求,大文件/多文件上传,文件下载,上传下载均有进度。支持304缓存,自定义缓存,302/303重定向,支持代理服务器访问地址(如: Google)。NoHttp是队列,自动为请求排队,可以取消指定请求, 可以取消队列所有请求,亦可以停止队列。支持请求String、Bitmap、Json、JavaBean,可自定义扩展请求类型。Request对象包涵参数、文件、请求头等;Response对象包涵响应内容,响应头等信息,Cookie。使用Gradle构建时添加依赖:// 引用最新版 compile 'com.yolanda.nohttp:nohttp: ' // 或则引用指定版本 compile 'com.yolanda.nohttp:nohttp:1.0.0'一. 请求1.请求String数据// 请求对象 Request request = NoHttp.createStringRequest(url, requestMethod); //添加请求头 request.addHeader("AppVersioin", "2.0"); // 添加请求参数 request.add("userName", "yolanda"); //上传文件 request.add("file", new FileBinary(file)); ...2.请求Json数据// JsonObject Request request = NoHttp.createJsonObjectRequest(url, reqeustMethod); queue.add(what, request, responseListener); … // JsonArray Request request = NoHttp.createJsonArrayRequest(url, reqeustMethod); queue.add(what, request, responseListener);3. 请求Bitmap数据Request request = NoHttp.createImageRequest(url, requestMethod); ...4. 取消请求取消单个请求Request request = NoHttp.createStringRequest(url); ... request.cancel();从队列中取消指定的请求Request request = NoHttp.createStringRequest(url); request.setCancelSign(sign); … queue.cancelBySign(sign);取消队列中所有请求queue.cancelAll();停止队列RequestQueue queue = NoHttp.newRequestQueue(); ... queue.stop();5. 同步请求// 在当前线程发起请求,在线程这么使用 Request request = NoHttp.createStringRequest(url); Response response = NoHttp.startRequestSync(request); if (response.isSucceed()) {     // 请求成功 } else {     // 请求失败 }二. 缓存1. Http标准协议的缓存,比如响应码是304时现在很多公司使用了RESTFUL风格来写Http API,所以这个是必须有的。Request request = NoHttp.createJsonObjectRequest(url); // NoHttp本身是RESTFUL风格的标准Http协议,所以这里不用设置或者设置为DEFAULT request.setCacheMode(CacheMode.DEFAULT); ...2. 当请求服务器失败的时候,读取缓存Request request = NoHttp.createJsonObjectRequest(url); // 非标准Http协议,改变缓存模式为REQUEST_FAILED_READ_CACHE request.setCacheMode(CacheMode.REQUEST_FAILED_READ_CACHE); ...3. 如果发现有缓存直接成功,没有缓存才请求服务器我们知道ImageLoader的核心除了内存优化外,剩下一个就是发现把内地有图片则直接使用,没有则请求服务器,所以NoHttp这一点非常使用做一个ImageLoader。Request request = NoHttp.createJsonObjectRequest(url); // 非标准Http协议,改变缓存模式为IF_NONE_CACHE_REQUEST request.setCacheMode(CacheMode.IF_NONE_CACHE_REQUEST); ...请求图片,缓存图片。// 如果没有缓存才去请求服务器,否则使用缓存,缓存图片演示 Request request = NoHttp.createImageRequest(imageUrl); request.setCacheMode(CacheMode.IF_NONE_CACHE_REQUEST); ...4. 仅仅读取缓存Request request = NoHttp.createJsonObjectRequest(url); // 非标准Http协议,改变缓存模式为ONLY_READ_CACHE request.setCacheMode(CacheMode.ONLY_READ_CACHE); ...注意:缓存不管是String、Json、图片还是任何请求都可以被NoHttp缓存二、响应OnResponseListener responseListener = new OnResponseListener() {     @Override     public void onStart(int what) {         // 请求开始时,可以显示一个Dialog     }     @Override     public void onFinish(int what) {         // 请求接受时,关闭Dialog     }     @Override     public void onSucceed(int what, Response response) {         // 接受请求结果         String result = response.get();         // Bitmap imageHead = response.get(); // 如果是bitmap类型,都是同样的用法     }     @Override     public void onFailed(int what, String url, Object tag, Exception exception, ...) {         // 请求失败或者发生异常         // 这里根据exception处理不同的错误,比如超时、网络不好等     } };三. 自定义请求类型: FastJsonRequest1.定义请求对象public class FastJsonRequest extends RestRequestor { public FastJsonRequest(String url) {     super(url); } public FastJsonRequest(String url, RequestMethod requestMethod) {     super(url, requestMethod); } @Override public JSONObject parseResponse(String url, Headers headers, byte[] responseBody) {     String result = StringRequest.parseResponseString(url, headers, responseBody);     JSONObject jsonObject = null;     if (!TextUtils.isEmpty(result)) {         jsonObject = JSON.parseObject(result);     } else {         // 这里默认的错误可以定义为你们自己的数据格式         jsonObject = JSON.toJSON("{}");     }     return jsonObject; } @Override public String getAccept() {     // 告诉服务器你接受什么类型的数据, 会添加到请求头的Accept中     return "application/json;q=1"; } }2.使用自定义请求-和NoHttp默认请求没有区别Request mRequest = new FastJsonRequest(url, requestMethod); queue.add(what, mRequest, responseListener);五. 下载文件发起下载请求//下载文件 downloadRequest = NoHttp.createDownloadRequest(url, fielDir, fileName, true, false); // what 区分下载 // downloadRequest 下载请求对象 // downloadListener 下载监听 CallServer.getDownloadInstance().add(0, downloadRequest, downloadListener);暂停或者停止下载downloadRequest.cancel();监听下载过程private DownloadListener downloadListener = new DownloadListener() {     @Override     public void onStart(int what, boolean resume, long preLenght, Headers header, long count) {     }     @Override     public void onProgress(int what, int progress, long downCount) {         // 更新下载进度     }     @Override     public void onFinish(int what, String filePath) {     }     @Override     public void onDownloadError(int what, StatusCode code, CharSequence message) {     }     @Override     public void onCancel(int what) {     } }; 标签:NoHttp

80,349

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧