關(guān)于WebView采坑實(shí)錄,以及解決方案

這邊總結(jié)幾個(gè)WebView的常見(jiàn)問(wèn)題暮胧,以及相應(yīng)的解決方法

一问麸、重定向問(wèn)題

問(wèn)題描述:我們從網(wǎng)頁(yè)A跳到網(wǎng)頁(yè)B,但是跳轉(zhuǎn)到B的過(guò)程其實(shí)經(jīng)歷了C頁(yè)面席舍,有C頁(yè)面重定向到達(dá)的B哮笆,A->(C->B),這個(gè)時(shí)候想要從B返回A,使用webview的goBack方法脚曾,會(huì)直接到C启具,由C又會(huì)回到B珊泳,導(dǎo)致無(wú)法跳出。

解決:?jiǎn)栴}的原因是因?yàn)槲以趙ebview的shouldOverrideUrlLoading里使用view.loadUrl(url)薯演,并且返回true導(dǎo)致秧了。查閱官方文檔,對(duì)于shouldOverrideUrlLoading的解釋是這樣的:

    /**
     * Give the host application a chance to take over the control when a new
     * url is about to be loaded in the current WebView. If WebViewClient is not
     * provided, by default WebView will ask Activity Manager to choose the
     * proper handler for the url. If WebViewClient is provided, return true
     * means the host application handles the url, while return false means the
     * current WebView handles the url.
     * This method is not called for requests using the POST "method".
     *
     * @param view The WebView that is initiating the callback.
     * @param url The url to be loaded.
     * @return True if the host application wants to leave the current WebView
     *         and handle the url itself, otherwise return false.
     * @deprecated Use {@link #shouldOverrideUrlLoading(WebView, WebResourceRequest)
     *             shouldOverrideUrlLoading(WebView, WebResourceRequest)} instead.
     */
    @Deprecated
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        return false;
    }

簡(jiǎn)單來(lái)說(shuō)衡创,return true 表示webview不會(huì)幫你處理內(nèi)部跳轉(zhuǎn)璃氢,而是根據(jù)你自己的代碼實(shí)現(xiàn)(webView.loadUrl)狮辽,反之巢寡,webview內(nèi)部會(huì)幫你處理跳轉(zhuǎn);
簡(jiǎn)單舉個(gè)例子:這邊的http://3g.cib.com.cn/home/00000.html會(huì)重定向到https://mobile.cib.com.cn/netbank/cn/index.html椰苟,打印跳轉(zhuǎn)后的歷史堆棧:

  • 使用webView.loadUrl,return true 方式
WebHistoryItemChromium[ mOriginalUrl=http://3g.cib.com.cn/home/00000.html,  mUrl=http://3g.cib.com.cn/home/00000.html], WebHistoryItemChromium[ mOriginalUrl=https://mobile.cib.com.cn/netbank/cn/index.html,  mUrl=https://mobile.cib.com.cn/netbank/cn/index.html]]]
  • 使用默認(rèn)處理 return false 方式
 WebHistoryItemChromium[ mOriginalUrl=http://3g.cib.com.cn/home/00000.html, mUrl=https://mobile.cib.com.cn/netbank/cn/index.html]]]

可以看到谦絮,前者生成了2條記錄须误,后者只有1條記錄,這樣使用webview.goBack就不會(huì)跳到重定向頁(yè)面了京痢。另外考慮到類似tel:xxx的url,webview無(wú)法識(shí)別的問(wèn)題臭家,需要對(duì)鏈接做一次過(guò)濾:

 @Override public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (TextUtil.isEmpty(url)) {
      return true;
    }
    if (url.startsWith("http://") || url.startsWith("https://")) {
      return false;
    } else {
      //todo 自行處理
      return true;
    }
  }

二方淤、通過(guò)一個(gè)頁(yè)面重復(fù)多次進(jìn)行攔截返回的頁(yè)面

問(wèn)題描述:例如https://3g.cib.com.cn/app/00282.html這個(gè)頁(yè)面携茂,webview在跳轉(zhuǎn)到這個(gè)頁(yè)面時(shí),其實(shí)連續(xù)跳轉(zhuǎn)了2次讳苦,這個(gè)導(dǎo)致返回的會(huì)到前面一個(gè)相同的頁(yè)面壳繁,而之后又會(huì)相同的頁(yè)面產(chǎn)生棋凳,導(dǎo)致返回不了子寓。

解決:這個(gè)問(wèn)題解決其實(shí)很簡(jiǎn)單,webview跳轉(zhuǎn)返回除了goBack之外還有一個(gè)goBackOrForward方法

    /**
     * Goes to the history item that is the number of steps away from
     * the current item. Steps is negative if backward and positive
     * if forward.
     *
     * @param steps the number of steps to take back or forward in the back
     *              forward list
     */
    public void goBackOrForward(int steps) {
        checkThread();
        mProvider.goBackOrForward(steps);
    }

這個(gè)方法可以直接前進(jìn)或者返回多級(jí)袜爪,于是我們只要在返回時(shí)檢測(cè)歷史隊(duì)列中的相同url,直接跳過(guò)相同的url穗慕,返回2級(jí)就可以了goBackOrForward(-2)

三、onPageFinished監(jiān)聽(tīng)不到url跳轉(zhuǎn)

問(wèn)題描述:某些情況下怀各,webview在處理頁(yè)面一些內(nèi)部跳轉(zhuǎn)時(shí)onPageFinished沒(méi)有調(diào)用

解決:在onLoadResource監(jiān)聽(tīng),onLoadResource是資源加載寿酌,只要頁(yè)面資源變化,這個(gè)方法就會(huì)執(zhí)行

四硕蛹、webview銷毀

問(wèn)題描述:webview資源不銷毀會(huì)引起內(nèi)存泄露法焰,相關(guān)部分可以查看更加具體的文章 鏈接

解決

  if (webView != null) {
      //webView.removeJavascriptInterface("android"); //刪除jsbridge
      webView.setWebChromeClient(null);
      webView.setWebViewClient(null);
      webView.getSettings().setJavaScriptEnabled(false);
      webView.clearCache(true);
      webView.removeAllViews();

      if (webView.getParent() instanceof ViewGroup) {
        ((ViewGroup) webView.getParent()).removeView(webView);
      }
      webView.destroy();
    }

五埃仪、支持加載Https和Http混合模式

問(wèn)題描述:在Android5.0以下卵蛉,默認(rèn)是采用的MIXED_CONTENT_ALWAYS_ALLOW模式傻丝,即總是允許WebView同時(shí)加載Https和Http;而從Android5.0開(kāi)始,默認(rèn)用MIXED_CONTENT_NEVER_ALLOW模式幌氮,即總是不允許WebView同時(shí)加載Https和Http。

解決

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
      set.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
    }

六韭畸、js對(duì)象注入漏洞

問(wèn)題描述:4.2以前胰丁,通過(guò)JavaScript锦庸,可以訪問(wèn)當(dāng)前設(shè)備的SD卡上面的任何東西蒲祈,甚至是聯(lián)系人信息,短信等扬卷。可以看相關(guān)報(bào)道:烏云

解決
Android WebView 使用漏洞

六咱枉、js 方法的混淆

問(wèn)題描述:webview與js交互的時(shí)候徒恋,需要使用自定義方法入挣,這個(gè)方法名是不能被混淆的

解決
為了解決上述js漏洞問(wèn)題,原則上所有定義的js方法都應(yīng)該加上@JavascriptInterface 风皿,而這些被加了@JavascriptInterface 的方法keep起來(lái)就好了

-keepattributes *Annotation*  
-keepattributes *JavascriptInterface*
-keep public class org.mq.study.webview.DemoJavaScriptInterface{
    public <methods>;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市夷恍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌酿雪,老刑警劉巖指黎,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異杂彭,居然都是意外死亡吓揪,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)团秽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)习勤,“玉大人,你說(shuō)我怎么就攤上這事姻报。” “怎么了损肛?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵治拿,是天一觀的道長(zhǎng)笆焰。 經(jīng)常有香客問(wèn)我,道長(zhǎng)嚷掠,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮霹娄,結(jié)果婚禮上犬耻,老公的妹妹穿的比我還像新娘。我一直安慰自己枕磁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著峭咒,像睡著了一般纪岁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上漩氨,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音叫惊,去河邊找鬼款青。 笑死,一個(gè)胖子當(dāng)著我的面吹牛霍狰,可吹牛的內(nèi)容都是我干的抡草。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蔗坯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼康震!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起宾濒,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤腿短,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后橘忱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卸奉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年钝诚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片择卦。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡敲长,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出秉继,到底是詐尸還是另有隱情祈噪,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布尚辑,位于F島的核電站辑鲤,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏杠茬。R本人自食惡果不足惜月褥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瓢喉。 院中可真熱鬧宁赤,春花似錦、人聲如沸栓票。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至佛猛,卻和暖如春惑芭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背继找。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工遂跟, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人婴渡。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓幻锁,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親缩搅。 傳聞我的和親對(duì)象是個(gè)殘疾皇子越败,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容