Android Webview的postUrl與loadUrl加載頁面實例
關(guān)于Android的webview,用過的想必都不會陌生。這里我就不說webview的基本用法了,想要知道的可以去網(wǎng)上百多,有很多介紹webview基本用法的。
本文要介紹的主要是在項目過程中使用webview的postUrl遇到的坑。
1、使用場景如下:
webview在加載H5鏈接時,默認是使用loadUrl進行加載,如果你設(shè)置了緩存屬性(進行緩存),在顯示的H5頁面內(nèi)點擊跳轉(zhuǎn)到另外一個頁面后,按回退鍵,可以正常的返回到上一個頁面,因為進行了緩存設(shè)置。但是如果使用postUrl進行加載,即使你設(shè)置的緩存屬性是進行設(shè)置,當(dāng)你調(diào)轉(zhuǎn)到另外一個頁面后,按回退鍵,不會緩存之前的頁面,而是重新調(diào)用postUrl進行加載。這時問題就來了,同樣是進行加載,第一次的postUrl能夠正常加載,重新加載會加載失敗,沒有內(nèi)容顯示。是不是很有意思,為什么會出現(xiàn)這樣的情況呢,通過抓包發(fā)現(xiàn),雖然加載的是同樣一個鏈接,但是重新加載的請求屬性為空,導(dǎo)致加載失敗。
2、如何解決:
既然找到了原因,請求屬性為空,肯定是有解決辦法的,那就手動設(shè)置請求屬性,重新加載。如何手動設(shè)置,首先你肯定是要能夠拿到請求的所有內(nèi)容和參數(shù)。用過webview的人相必都很熟悉它的setWebViewClient方法。該方法內(nèi)部有shouldInterceptRequest方法能夠拿到請求的所有內(nèi)容。不多說了,先上代碼。
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { if(Build.VERSION.SDK_INT >= 21){ if(!request.getMethod().equalsIgnoreCase("post")){ return super.shouldInterceptRequest(view, request); } } DataOutputStream os = null; try { URL mUrl = new URL(url); HttpURLConnection connection = (HttpURLConnection) mUrl.openConnection(); connection.setDoInput(true); connection.setDoOutput(true); connection.setUseCaches(false); connection.setRequestMethod("POST"); if(Build.VERSION.SDK_INT >= 21){ Iterator headerKeys=request.getRequestHeaders().keySet().iterator(); while(headerKeys.hasNext()){ String key=headerKeys.next(); connection.setRequestProperty(key,request.getRequestHeaders().get(key)); } } connection.setRequestProperty("content-type","application/x-www-form-urlencoded"); os = new DataOutputStream(connection.getOutputStream()); os.write(EncodingUtils.getBytes(postData, "BASE64")); os.flush(); return new WebResourceResponse("text/html", connection.getContentEncoding(), connection.getInputStream()); } catch (Exception e) { e.printStackTrace(); }finally { if(os!=null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } } return super.shouldInterceptRequest(view, request); } }); webView.postUrl(url, EncodingUtils.getBytes(postData, "BASE64"));
該方法有個缺陷,只在Android 5.0.0以上的Api才有,5.0.0以下的Api是沒有此方法的,這也是一個坑,不能兼容所有機型。通過該方法中的setRequestProperty方法重新設(shè)置了請求屬性,然后使用postUrl進行重新加載,可以解決按回退鍵后頁面的重新恢復(fù)。注意,由于post加載是不能緩存的,因此在設(shè)置緩存屬性時一定要設(shè)置成重新加載屬性。
3、解決后出現(xiàn)的問題:
問題看似解決了,但是此方法會有坑。如果你仔細研究該方法,你會發(fā)現(xiàn)shouldInterceptRequest方法是在整個加載過中都調(diào)用了的。如果你進行抓包,你會發(fā)現(xiàn),從開始加載鏈接到H5頁面中加載的每一個請求,該方法都會被調(diào)用,簡單的說就是有多少個請求,該方法就會調(diào)用多少次。如果你的頁面中還有一次post請求,那么問題就來了,你需要將第二次post請求的請求內(nèi)容與第一次的進行對比,對比后選擇到底是加載第一次的頁面,還是加載第二次的頁面,否則就會默認加載第一次的post頁面。
4、結(jié)論
webview的H5頁面加載最好使用loadUrl方式,如果使用postUrl方式進行加載,你需要重寫整個setWebViewClient方法,當(dāng)中會出很多坑,不建議這樣做。
以上這篇Android Webview的postUrl與loadUrl加載頁面實例就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
- 深入解析Android中的setContentView加載布局原理
- 淺析Android Dialog中setContentView()方法
- Android開發(fā)中setContentView和inflate的區(qū)別分析
- Android開發(fā)微信小程序頁面的圖文教程
- Android 登錄頁面的實現(xiàn)代碼(密碼顯示隱藏、EditText 圖標(biāo)切換、限制輸入長度)
- Android Studio使用recyclerview實現(xiàn)展開和折疊功能(在之前的微信頁面基礎(chǔ)之上)
- Android通過ViewModel保存數(shù)據(jù)實現(xiàn)多頁面的數(shù)據(jù)共享功能
- Android仿微信左右滑動點擊切換頁面和圖標(biāo)
- Android仿淘寶訂單頁面效果
- Android使用setContentView實現(xiàn)頁面的轉(zhuǎn)換效果
相關(guān)文章
基于Android CALL && SendMes Test的相關(guān)介紹
本篇文章小編為大家介紹,Android CALL && SendMes Test 需要的朋友參考下2013-04-04Android中ViewPager帶來的滑動卡頓問題解決要點解析
這里我們主要針對ViewGroup的SwipeRefreshLayout中引入ViewPager所引起的滑動沖突問題進行討論,一起來看一下Android中ViewPager帶來的滑動卡頓問題解決要點解析:2016-06-06Android 8.0系統(tǒng)中應(yīng)用圖標(biāo)的適配技巧
今天小編就為大家分享一篇關(guān)于Android 8.0系統(tǒng)中應(yīng)用圖標(biāo)的適配技巧,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10Android利用Canvas標(biāo)點畫線并加入位移動畫(2)
這篇文章主要為大家詳細介紹了Android利用Canvas標(biāo)點畫線并加入位移動畫的第二篇,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-09-09Android編程中Intent實現(xiàn)頁面跳轉(zhuǎn)功能詳解
這篇文章主要介紹了Android編程中Intent實現(xiàn)頁面跳轉(zhuǎn)功能,結(jié)合實例形式分析了Android Intent實現(xiàn)頁面跳轉(zhuǎn)功能的具體步驟與相關(guān)注意事項,需要的朋友可以參考下2017-07-07Android設(shè)備間實現(xiàn)藍牙(Bluetooth)共享上網(wǎng)
這篇文章主要為大家詳細介紹了Android設(shè)備間實現(xiàn)藍牙(Bluetooth)共享上網(wǎng)的方法,主要以圖片的方式向大家展示藍牙共享上網(wǎng)2016-03-03