国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Android 性能優(yōu)化:內(nèi)存篇】——WebView 內(nèi)存泄露治理

這篇具有很好參考價(jià)值的文章主要介紹了【Android 性能優(yōu)化:內(nèi)存篇】——WebView 內(nèi)存泄露治理。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

背景:筆者在公司項(xiàng)目中優(yōu)化內(nèi)存泄露時(shí)發(fā)現(xiàn)WebView 相關(guān)的內(nèi)存泄露問題非常經(jīng)典,一個 Fragment 頁面使用的 WebView 有多條泄露路徑,故記錄下。

Fragment、Activity 使用WebView不釋放

項(xiàng)目中一個Fragment 使用 Webview,在 Fragment onDestroyView 時(shí)候卻沒有釋放,釋放 WebView 還不簡單嘛,于是筆者在 Fragment 的 onDestroyView 補(bǔ)充了如下代碼:

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

然而,這樣其實(shí)釋放不全,還是抓到其他的泄露路徑

安卓 view內(nèi)存泄漏,性能優(yōu)化,android,性能優(yōu)化

如圖GC 引用鏈:AwContents->WebVIew->View.LinsenerInfo->WebViewFragment

原因是使用 WebView的時(shí)候,注冊了OnFocusChangeListener

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

因此,釋放 WebView的時(shí)候,還需要把注冊的一些Listener 釋放

WebView 釋放不全

上面介紹了釋放 WebView 資源的時(shí)候釋放不全的例子,那么怎樣才能將用到的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,記得也需要釋放

網(wǎng)上,還有說需要調(diào)用

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

上面的接口慎用,因?yàn)樗鼈兪菍θ稚У?,不只?dāng)前WebView!

按上面兩個步驟解決完,筆者以為不會再發(fā)生泄漏,誰知道還是抓到第三條泄露路徑??!

安卓 view內(nèi)存泄漏,性能優(yōu)化,android,性能優(yōu)化

GC 引用鏈:AwContents->BannerView->Banner->CardView->Container->AdView->匿名內(nèi)部類AdListener->WebViewFragment

匿名內(nèi)部類導(dǎo)致 WebView泄露

按上面描述的引用鏈,匿名內(nèi)部類隱式持有外部類 Fragment 的引用,而這個匿名內(nèi)部類AdShowListener 剛好是 AdView 持有的, AdView 本質(zhì)上是一個 WebView.

解法很常規(guī):把匿名內(nèi)部類改為靜態(tài)內(nèi)部類,然后靜態(tài)內(nèi)部類里使用的 Fragment 改為弱引用,并且 Fragment 銷毀的時(shí)候,AdShowListener 置空。

到此,筆者以為不會再發(fā)生內(nèi)存泄露了,怎知,還是抓到了,這次抓的是包裹 Fragment 的Activity 作為 Context 被 webview 持有

安卓 view內(nèi)存泄漏,性能優(yōu)化,android,性能優(yōu)化

意不意外,驚不驚喜?

GC 引用鏈:AwContents->WebView->WebViewActivity, WebViewActivity 作為 Conext 被 WebView 持有

因?yàn)?Fragment 初始化 WebView 的時(shí)候 使用了 getActivity(),context 一直被 WebView 內(nèi)核持有,筆者猜測部分系統(tǒng)會有這種問題。這種問題是否無解了?山重水復(fù)疑無路,柳暗花明又一寸,筆者意外發(fā)現(xiàn)有個類 MutableContextWrapper 可以使用。

MutableContextWrapper 切換 Context

初始化 WebView 的時(shí)候使用AppContext,在 Activity 使用 Webview 的時(shí)候切換為 Activity,最后銷毀 WebView 之前再切換回 AppContext

為什么在Activity 使用WebView的時(shí)候切換到Activity 呢?因?yàn)閃ebView 中的可能有些場景依賴 Activity 如:彈窗Dialog,Context 為AppContext 會發(fā)生崩潰。

private WebView webview;
//初始化Webview
MutableContextWrapper contextWrapper = new MutableContextWrapper(getAppContext());
webview = new WebView(contextWrapper);

//在Activity中使用
private WebView acquireWebView(Activity activity) {
    //緩存中的webview
    MutableContextWrapper 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();
  }
}

至此,沒有再抓到泄露路徑。

總結(jié)

本文列舉了項(xiàng)目中治理 WebView 內(nèi)存泄露的手段:

1)Fragment、Activity 銷毀時(shí)釋放WebView。

2)釋放WebView 需要釋放完全,WebView 注冊的各種監(jiān)聽器都需要釋放。

3)同時(shí)要考慮Fragment、Activity 有沒用到匿名內(nèi)部類,如果有要改成靜態(tài)內(nèi)部類,并且要靜態(tài)內(nèi)部類有使用Fragment、Activity的話要使用弱引用。

4)初始化 WebView 的時(shí)候使用AppContext,在 Activity 使用 Webview 的時(shí)候切換為 Activity,最后銷毀 WebView 之前再切換回 AppContext。文章來源地址http://www.zghlxwxcb.cn/news/detail-765057.html

到了這里,關(guān)于【Android 性能優(yōu)化:內(nèi)存篇】——WebView 內(nèi)存泄露治理的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Android 開發(fā)必備知識點(diǎn)及面試題匯總(Android+Java+算法+性能優(yōu)化+四大組件……),騰訊安卓開發(fā)面試

    Android 開發(fā)必備知識點(diǎn)及面試題匯總(Android+Java+算法+性能優(yōu)化+四大組件……),騰訊安卓開發(fā)面試

    5.請介紹下 AsyncTask的內(nèi)部實(shí)現(xiàn),適用的場景是 AsyncTask 內(nèi)部也是 Handler 機(jī)制來完成的,只不過 Android 提供了執(zhí)行框架來提供線程池來 執(zhí)行相應(yīng)地任務(wù),因?yàn)榫€程池的大小問題,所以 AsyncTask 只應(yīng)該用來執(zhí)行耗時(shí)時(shí)間較短的任務(wù), 比如 HTTP 請求,大規(guī)模的下載和數(shù)據(jù)庫的更改不

    2024年04月15日
    瀏覽(26)
  • 【Jvm】性能調(diào)優(yōu)(拓展)Jprofiler如何監(jiān)控和解決死鎖、內(nèi)存泄露問題

    【Jvm】性能調(diào)優(yōu)(拓展)Jprofiler如何監(jiān)控和解決死鎖、內(nèi)存泄露問題

    Jprofilers是針對Java開發(fā)的 性能分析工具(免費(fèi)試用10天) , 可以對Java程序的 內(nèi)存,CPU,線程,GC,鎖 等進(jìn)行監(jiān)控和分析 , 本人IDEA版本是 2020.2.2 ,選擇的Jprofiler版本是 12.0 (早期的版本是純英文的, 12.0支持中文 ,安裝主要考慮是否與IDEA插件兼容即可) 進(jìn)入Jprofiler官網(wǎng)下載 - Jprofiler 版本這

    2024年02月19日
    瀏覽(24)
  • 安卓部分手機(jī)使用webview加載鏈接后白屏(Android低版本會出現(xiàn)的問題)

    安卓部分手機(jī)使用webview加載鏈接后白屏(Android低版本會出現(xiàn)的問題)

    大爺:小伙我這手機(jī)怎么打開你們呢這個是白屏什么都不顯示。 大娘:小伙我這也是打開你們呢這功能,就是一個白屏什么也沒有,你們呢的應(yīng)用不會有病毒吧。 小伙:我的手機(jī)也正常; 同事:我的也正??梢燥@示; 小伙:你們都是什么手機(jī)型號; 大爺:我的Android7.1.1

    2024年04月15日
    瀏覽(22)
  • 安卓進(jìn)階(一)App性能優(yōu)化

    安卓進(jìn)階(一)App性能優(yōu)化

    性能優(yōu)化的目的是為了讓應(yīng)用程序App 更快、更穩(wěn)定 更省。具體介紹如下: 更快:應(yīng)用程序 運(yùn)行得更加流暢、不卡頓,能快速響應(yīng)用戶操作 更穩(wěn)定:應(yīng)用程序 能 穩(wěn)定運(yùn)行 解決用戶需求,在用戶使用過程中不出現(xiàn)應(yīng)用程序崩潰(Crash) 和 無響應(yīng)(ANR)的問題 更?。汗?jié)省耗費(fèi)

    2024年02月07日
    瀏覽(27)
  • linux 性能優(yōu)化-內(nèi)存優(yōu)化

    linux 性能優(yōu)化-內(nèi)存優(yōu)化

    CPU 管理一樣,內(nèi)存管理也是操作系統(tǒng)最核心的功能之一。內(nèi)存主要用來存儲系統(tǒng)和應(yīng) 用程序的指令、數(shù)據(jù)、緩存等。 1.1.1.日常生活常說的內(nèi)存是什么? 我的筆記本電腦內(nèi)存就是 8GB 的 這個內(nèi)存其實(shí)是物理內(nèi)存 物理內(nèi)存也稱為主存,大多數(shù)計(jì)算機(jī)用的主存都是動態(tài)隨機(jī)訪問內(nèi)

    2024年02月04日
    瀏覽(26)
  • Linux性能優(yōu)化--性能工具:系統(tǒng)內(nèi)存

    Linux性能優(yōu)化--性能工具:系統(tǒng)內(nèi)存

    本章概述了系統(tǒng)級的Linux內(nèi)存性能工具。本章將討論這些工具可以測量的內(nèi)存統(tǒng)計(jì)信息,以及如何使用各種工具收集這些統(tǒng)計(jì)結(jié)果。閱讀本章后,你將能夠: 理解系統(tǒng)級性能的基本指標(biāo),包括內(nèi)存的使用情況。 明白哪些工具可以檢索這些系統(tǒng)級性能指標(biāo)。 每一種系統(tǒng)級Linu

    2024年02月07日
    瀏覽(22)
  • Linux性能優(yōu)化--性能工具:特定進(jìn)程內(nèi)存

    Linux性能優(yōu)化--性能工具:特定進(jìn)程內(nèi)存

    本章介紹的工具使你能診斷應(yīng)用程序與內(nèi)存子系統(tǒng)之間的交互,該子系統(tǒng)由Linux內(nèi)核和CPU管理。由于內(nèi)存子系統(tǒng)的不同層次在性能上有數(shù)量級的差異,因此,修復(fù)應(yīng)用程序使其有效地使用內(nèi)存子系統(tǒng)會對程序性能產(chǎn)生巨大的影響。 閱讀本章后,你將能夠: 確定一個應(yīng)用程序使

    2024年02月07日
    瀏覽(28)
  • linux性能優(yōu)化-內(nèi)存原理

    linux性能優(yōu)化-內(nèi)存原理

    只有內(nèi)核才可以直接訪問物理內(nèi)存,Linux內(nèi)核給每個進(jìn)程都提供了一個獨(dú)立的虛擬地址空間,并且這個地址空間是連續(xù)的。這樣,進(jìn)程通過訪問虛擬內(nèi)存來訪問內(nèi)存。 虛擬地址空間的內(nèi)部又被分為內(nèi)核空間和用戶空間兩部分,不同字長(也就是單個 CPU 指令可以處理數(shù)據(jù)的最

    2024年02月01日
    瀏覽(23)
  • 前端性能優(yōu)化——內(nèi)存問題

    前端性能優(yōu)化——內(nèi)存問題

    過高的內(nèi)存資源占用會導(dǎo)致 Web 應(yīng)用變慢,甚至崩潰??梢酝ㄟ^ window.performance.memory 查看瀏覽器的內(nèi)存限制等信息。 Web 前端開發(fā)中存在許多內(nèi)存問題,下面是一些常見的內(nèi)存問題: 內(nèi)存泄漏:當(dāng)一個對象不再被使用,但仍然占用著內(nèi)存空間,就會導(dǎo)致內(nèi)存泄漏問題。在 Web

    2024年02月16日
    瀏覽(33)
  • Unity 性能優(yōu)化二:內(nèi)存問題

    Unity 性能優(yōu)化二:內(nèi)存問題

    目錄 策略導(dǎo)致的內(nèi)存問題 GFX內(nèi)存 紋理資源 壓縮格式 Mipmap 網(wǎng)格資源 Read/Write 頂點(diǎn)數(shù)據(jù) 骨骼 靜態(tài)合批 Shader資源 Reserved Memory RenderTexture 動畫資源 音頻資源? 字體資源 粒子系統(tǒng)資源 Mono堆內(nèi)存 1. Assetbundle 打包的時(shí)候,單個資源被重復(fù)打包,可以把依賴的資源,單個打包,通過

    2024年02月15日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包