Android5.1系统WebView内存泄漏场景
来源:互联网 发布:淘宝商品如何做图 编辑:程序博客网 时间:2024/05/16 06:10
问题现象
(该文章,引自零号路的私人博客,本人在浏览框架的开发过程中,用该方式,规避了内存泄露的问题。)
在Android5.1系统中,会发现App存在 WebView 泄漏情况,还比较严重。并且只是发生在 Android 5.1 系统。
GC roots 如下:
每新打开一次这个WebViewActivity,就会发生就会发生一次改Webview实例无法释放,新增一个对象。
上图中的两个 AppSearchWebView实例,就是由于打开了两次导致。
问题分析
出现了这个问题分析起来还是比较简单的,根据这个引用关系,我们可以直观的看到是由于 Appsearch(extends Application)的 mComponentCallbacks 一直在强引用AWComponentCallbacks,导致无法释放。然后AWComponentCallbacks -> AWContents > AppSearchWebView。
通过分析代码发现关键在于 AwContents 这里的 AwComponentsCallbacks 为什么没有释放。
@Override public void onAttachedToWindow() { if (isDestroyed()) return; if (mIsAttachedToWindow) { Log.w(TAG, "onAttachedToWindow called when already attached. Ignoring"); return; }...... mComponentCallbacks = new AwComponentCallbacks(); mContext.registerComponentCallbacks(mComponentCallbacks); } @Override public void onDetachedFromWindow() { if (isDestroyed()) return; if (!mIsAttachedToWindow) { Log.w(TAG, "onDetachedFromWindow called when already detached. Ignoring"); return; }...... if (mComponentCallbacks != null) { mContext.unregisterComponentCallbacks(mComponentCallbacks); mComponentCallbacks = null; }...... }
看这段代码看不出来什么问题,onAttach的时候 register,detach的时候 unregister, 不会存在问题。
但是为什么呢?
难道是由于 if (isDestroyed()) return 这条return引起的?
当调用 Webview.destroy() 后 这个判断 返回true。
我们看下哪里调用了 webview.destroy()
// source from WebViewActivity@Overrideprotected void onDestroy() { super.onDestroy(); if (mWebView != null) { mWebView.destroy(); }}
很多应用应该都是这么做的,包括系统浏览器,在Activity destroy的时候,调用 webview的destroy。并且一直工作的很好。
通过调试发现,确实是由于此调用导致的。onDestroy 发生在 onDetach 之前。
那为什么 android 5.1 之前的代码没有问题呢?
看下代码:
// AwContents.java @Override public void onDetachedFromWindow() { if (!mIsAttachedToWindow) { Log.w(TAG, "onDetachedFromWindow called when already detached. Ignoring"); return; }...... if (mComponentCallbacks != null) { mContext.unregisterComponentCallbacks(mComponentCallbacks); mComponentCallbacks = null; }......}
相对于 5.1 的代码少了那句 if (isDestroyed()) return;
规避方法
解决方案可以:在destroy之前,把webview 从 parent 中 remove 掉,同样可以提前detach。
protected void onDestroy() { if (mWebView != null) { ((ViewGroup) mWebView.getParent()).removeView(mWebView); mWebView.destroy(); mWebView = null; } super.onDestroy(); }
- Android5.1系统WebView内存泄漏场景
- HashMap内存泄漏场景
- webview内存泄漏问题
- WebView内存泄漏
- WebView内存泄漏记录
- Android WebView 内存泄漏
- WebView内存泄漏解决方法
- WebView内存泄漏解决方法
- WebView内存泄漏修复
- WebView内存泄漏--解决方法
- java内存泄漏常见场景
- Android 内存泄漏场景分析
- 解决webview内存泄漏问题
- Android---WebView内存泄漏解决方法
- Android WebView内存泄漏分析
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- Android WebView Memory Leak WebView内存泄漏
- linux下C++开发工具
- 并查集初学(2)LA 3644 & LA3027
- Android之十一实现登陆页面分析
- Linux下常用的C/C++开源Socket库
- map同步数据库/后台缓存
- Android5.1系统WebView内存泄漏场景
- Hash Compared & ELFHash 详解
- 桌面图标没有是解决方法windown
- 3D 游戏控制
- Spark中的各种action算子操作(java版)
- 对优秀程序员的思考
- 40个良好用户界面设计Tips
- 欢迎使用CSDN-markdown编辑器
- 奇奇怪怪的树形dp