当前位置: 首页 > news >正文

怡清源在慧聪网网站建设情况做装修业务呢有多少网站

怡清源在慧聪网网站建设情况,做装修业务呢有多少网站,免费的招标网有哪些,做行业导航网站好背景:笔者在公司项目中优化内存泄露时发现WebView 相关的内存泄露问题非常经典,一个 Fragment 页面使用的 WebView 有多条泄露路径,故记录下。 Fragment、Activity 使用WebView不释放 项目中一个Fragment 使用 Webview,在 Fragm…

背景:笔者在公司项目中优化内存泄露时发现WebView 相关的内存泄露问题非常经典,一个 Fragment 页面使用的 WebView 有多条泄露路径,故记录下。

Fragment、Activity 使用WebView不释放

项目中一个Fragment 使用 Webview,在 Fragment onDestroyView 时候却没有释放,释放 WebView 还不简单嘛,于是笔者在 Fragment 的 onDestroyView 补充了如下代码:

if (webView != null) {ViewGroup parent = (ViewGroup) webView.getParent();if (parent != null) {parent.removeView(webView);}webView.destroy();webview = null;
}

然而,这样其实释放不全,还是抓到其他的泄露路径

如图GC 引用链:AwContents->WebVIew->View.LinsenerInfo->WebViewFragment

原因是使用 WebView的时候,注册了OnFocusChangeListener

webView.setOnFocusChangeListener(new View.OnFocusChangeListener() {@Overridepublic void onFocusChange(View v, boolean hasFocus) {//省略}
});

因此,释放 WebView的时候,还需要把注册的一些Listener 释放

WebView 释放不全

上面介绍了释放 WebView 资源的时候释放不全的例子,那么怎样才能将用到的WebView 资源释放完全呢?

笔者封装了一个接口如下:

public void destroyWebView(WebView webView) {try {if (webView != null) {ViewGroup parent = (ViewGroup) webView.getParent();if (parent != null) {parent.removeView(webView);}webView.setOnTouchListener(null);webView.setOnKeyListener(null);webView.setOnFocusChangeListener(null);webView.setWebChromeClient(null);webView.setWebViewClient(null);webView.loadUrl("about:blank");webView.onPause();webView.removeAllViews();webView.destroyDrawingCache();webView.destroy();webView = null;}} catch (Throwable e) {e.printStackTrace();}
}

这样释放真的释放完全了?如果你使用的WebView 还注册了其他的Listener,记得也需要释放

网上,还有说需要调用

webView.pauseTimers();
webView.clearHistory();

上面的接口慎用,因为它们是对全局生效的,不只当前WebView!

按上面两个步骤解决完,笔者以为不会再发生泄漏,谁知道还是抓到第三条泄露路径!!

GC 引用链:AwContents->BannerView->Banner->CardView->Container->AdView->匿名内部类AdListener->WebViewFragment

匿名内部类导致 WebView泄露

按上面描述的引用链,匿名内部类隐式持有外部类 Fragment 的引用,而这个匿名内部类AdShowListener 刚好是 AdView 持有的, AdView 本质上是一个 WebView.

解法很常规:把匿名内部类改为静态内部类,然后静态内部类里使用的 Fragment 改为弱引用,并且 Fragment 销毁的时候,AdShowListener 置空。

到此,笔者以为不会再发生内存泄露了,怎知,还是抓到了,这次抓的是包裹 Fragment 的Activity 作为 Context 被 webview 持有

意不意外,惊不惊喜?

GC 引用链:AwContents->WebView->WebViewActivity, WebViewActivity 作为 Conext 被 WebView 持有

因为 Fragment 初始化 WebView 的时候 使用了 getActivity(),context 一直被 WebView 内核持有,笔者猜测部分系统会有这种问题。这种问题是否无解了?山重水复疑无路,柳暗花明又一寸,笔者意外发现有个类 MutableContextWrapper 可以使用。

MutableContextWrapper 切换 Context

初始化 WebView 的时候使用AppContext,在 Activity 使用 Webview 的时候切换为 Activity,最后销毁 WebView 之前再切换回 AppContext

为什么在Activity 使用WebView的时候切换到Activity 呢?因为WebView 中的可能有些场景依赖 Activity 如:弹窗Dialog,Context 为AppContext 会发生崩溃。

private WebView webview;
//初始化Webview
MutableContextWrapper contextWrapper = new MutableContextWrapper(getAppContext());
webview = new WebView(contextWrapper);//在Activity中使用
private WebView acquireWebView(Activity activity) {//缓存中的webviewMutableContextWrapper contextWrapper = (MutableContextWrapper) webView.getContext();contextWrapper.setBaseContext(activity);return webView;
}//销毁之前public void recycleWebView(WebView webView) {if (webView == null) {return;}MutableContextWrapper contextWrapper = (MutableContextWrapper) webView.getContext();contextWrapper.setBaseContext(getAppContext());destroyWebView(webview);}//销毁 webview 的接口
public void destroyWebView(WebView webView) {try {if (webView != null) {ViewGroup parent = (ViewGroup) webView.getParent();if (parent != null) {parent.removeView(webView);}webView.setOnTouchListener(null);webView.setOnKeyListener(null);webView.setOnFocusChangeListener(null);webView.setWebChromeClient(null);webView.setWebViewClient(null);webView.loadUrl("about:blank");webView.onPause();webView.removeAllViews();webView.destroyDrawingCache();webView.destroy();webView = null;}} catch (Throwable e) {e.printStackTrace();}
}

至此,没有再抓到泄露路径。

总结

本文列举了项目中治理 WebView 内存泄露的手段:

1)Fragment、Activity 销毁时释放WebView。

2)释放WebView 需要释放完全,WebView 注册的各种监听器都需要释放。

3)同时要考虑Fragment、Activity 有没用到匿名内部类,如果有要改成静态内部类,并且要静态内部类有使用Fragment、Activity的话要使用弱引用。

4)初始化 WebView 的时候使用AppContext,在 Activity 使用 Webview 的时候切换为 Activity,最后销毁 WebView 之前再切换回 AppContext。

http://www.yayakq.cn/news/658526/

相关文章:

  • 佛山行业网站设计公司对于网站开发有什么要求
  • 静态做网站国家建筑标准设计网
  • 站长工具2023最新国产百度浏览器打开
  • 如何用ps做网站平面图青岛网站建设
  • 纯静态网站seo娄底北京网站建设
  • asp.net网站开发上wordpress企业主题 免费
  • 个人网站可以做社交类型58同城 网站建设 成都
  • php是专门做网站的wordpress 主机安装教程
  • tp框架做的网站东莞南海网站制作
  • 温州 网站建设网站建设全包
  • 网站后台 教程建管家公司简介
  • 高校网络网站建设意义及措施焦作市网站建设公司
  • 潍坊外贸网站制作品牌vi设计设计生成
  • 传奇做网站做外贸的女生现状
  • 国土资源局加强网站建设小程序链接wordpress
  • 成都行业网站建设那里好海安公司网站建设
  • 营销型网站模板下载西安网站seo厂家
  • 淘宝找做网站湖南网络营销企业
  • 内蒙古建设安全监督网站平面设计学生作品集
  • joomla 2.5:你的网站建设_使用与管理seo技术秋蝉
  • 怎样创建网站的基本流程怎样不让网站自动跳转wap
  • 推介网站wordpress月亮主题
  • 义乌网站建站食品网站设计欣赏
  • 浙江网站建设公司猪八戒做网站排名
  • 做网站多钱一年南宁网站建设公司哪家专业
  • saas建站平台有哪些给设计公司起名大全
  • 国外知名网站学网络技术培训学校
  • 网络移动公司的网站建设北京南站
  • 工会网站建设可以wordpress友情链接做导航
  • 长沙网站优化分析wordpress滑块部分