Android開發(fā)之WebView(一)配置&小技巧

背景:原生時間緊沒時間開發(fā)任務量大的任務,而前端又閑著打醬油

方案:原生+webview混合開發(fā)

缺點:對于比較復雜的頁面,webview在性能上力不從心;且與原生通信頻繁也增加了隱藏的工作量

優(yōu)點:能自帶支持動態(tài)更新(js),能充分利用人力

一:WebView介紹

webview是一個基于webkit引擎,展示web頁面的控件。Android上的webview在低版本和高版本采用了不同的webkit版本內(nèi)核,Android4.4(19)后直接使用了Chrome內(nèi)核;WebView控件功能強大,除了具有一般View的屬性和設置外,還可以對url請求,頁面加載,渲染,頁面交互進行強大的處理。一般來說webview可單獨使用,也可聯(lián)合其工具類一起使用

移動應用的主體是webview,主要以網(wǎng)頁語言編寫,穿插Native功能的Hybrid App開發(fā)類型。激活webview為活躍狀態(tài),能正常執(zhí)行網(wǎng)頁的響應;當webview 的頁面被失去焦點切換到后臺不可見狀態(tài)onPause時,需要通知自己暫停所有的動作,比如DOM的解析,plugin的執(zhí)行,JavaScript的執(zhí)行等

二:WebView的作用

1,顯示和渲染web頁面

2,直接使用本地assets或者網(wǎng)絡上的html文件作為布局

3,可和JavaScript進行互相調(diào)用

三:WebView的使用方式

1,直接在布局文件里寫死

2,動態(tài)添加進viewgroup中

注:不管以哪種方式,都必須注意webview的銷毀,否則可能會造成內(nèi)存泄漏最終導致內(nèi)存溢出crash

四:WebView常用方法及說明

下面是WebView的一些常用的方法列舉,一些已經(jīng)過時的方法未列出

webview.loadUrl("www.baidu.com")  //加載url
webview.loadurl("javascript:jsmethod()")  //可以執(zhí)行js函數(shù),沒有返回值,其中jsmethod是js中定義的函數(shù)
webview.evaluateJavascript(String script, ValueCallback<String> resultCallback)  //script同上,有返回值
webview.setWebViewClient(new WebViewClient());   //設置webviewclient,通過重寫部分方法可以實現(xiàn)定制化的功能,攔截url,監(jiān)控資源加載狀態(tài)等
webview.setWebChromeClient(new WebChromeClient()   //設置WebChromeClient,重寫部分方法可以處理js的對話框,網(wǎng)址圖標,標題和加載進度等
webview.onPause()  //webview的生命周期方法,可于activity的生命周期綁定調(diào)用,通知webkit內(nèi)核暫停所有的動作,比如DOM的解析,plugin的執(zhí)行,JavaScript的執(zhí)行
webview.onResume   //webview的生命周期方法,可于activity的生命周期綁定調(diào)用,通知webkit內(nèi)核恢復所有的動作,比如DOM的解析,plugin的執(zhí)行,JavaScript的執(zhí)行
webview.pauseTimers()   //和onPause搭配使用,針對全應用程序的webview,會暫停所有webview的layout,parsing,JavaScriptTimer,可降低CPU功耗,達到省電的目的
webview.resumeTimers()  //和onResume搭配使用,恢復pauseTimers時的所有動作
webview.destroy()   //銷毀webview,一般在activity的onDestroy方法中調(diào)用,注意調(diào)用時需要先在父容器中移除webview,然后再銷毀,如:( (ViewGroup) webView.getParent()).removeView(webView);
webview.stopLoading()  //停止當前加載
webview.clearMatches()  //清除網(wǎng)頁查找的高亮匹配字符
webview.clearHistory()  //清除當前webview的歷史訪問記錄
webview.clearCache(true)  //清空網(wǎng)頁訪問留下的緩存數(shù)據(jù)(內(nèi)存+磁盤),為false時只清除內(nèi)存的
webview.loadUrl("about:blank")  //清空當前加載
webview.removeAllViews()  //清空所有子view

五:WebSettings的常用配置方法及說明

下面是WebSettings的一些常用的方法列舉,一些已經(jīng)過時的方法就沒有寫出來了

WebSettings settings = webView.getSettings();
String ua = settings.getUserAgentString();
// 添加userAgent,方便前端網(wǎng)頁判斷請求來源
settings.setUserAgentString(ua + "; app/1.0.0");
// 頁面中要與JavaScript交互,需要設置為true
settings.setJavaScriptEnabled(true);
// 設置允許JS彈窗
settings.setJavaScriptCanOpenWindowsAutomatically(true);
//保存表單數(shù)據(jù)
settings.setSaveFormData(true);
//將圖片調(diào)整到適合webview的大小
settings.setUseWideViewPort(true);
// 縮放至屏幕的大小
settings.setLoadWithOverviewMode(true);
//不支持縮放
settings.setSupportZoom(false);
//設置內(nèi)置的縮放控件,這個取決于setSupportZoom,如果setSupportZoom設置為false,則此處設置無效
settings.setBuildInZoomControls(true);
//設置可以訪問文件,如果此處設置為false,則webview的input標簽的type=‘file’將點擊無響應
settings.setAllowFileAccess(true);
//支持多窗口
settings.setSupportMultipleWindows(true);
//支持內(nèi)容重新布局,實戰(zhàn)發(fā)現(xiàn)此處如果設置為NARROW_COLUMN會導致某些手機顯示不能撐滿寬度問題
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
//支持自動加載圖片
settings.setLoadsImagesAutomatically(true);
//設置編碼格式
settings.setDefaultTextEncodingName("utf-8");
//設置默認字體大小
settings.setDefaultFontSize(16);
//特別注意,5.1以上默認禁止了https和http的混用,以下方式是開啟
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}

六:WebView常見問題

1,引起內(nèi)存泄露

在使用webview中,不管是寫在xml里還是動態(tài)生成的,都會不可避免的將當前的context傳入webview中,也就是webview持有當前activity的引用。在我們關閉activity的時候,如果此時webview還在加載就會導致activity無法被回收,造成內(nèi)存泄漏;總結來說,就是由于多個對象的生命周期不一致導致的無法同生同滅

一般不管是動態(tài)生成還是xml寫死,只要處理好了引用持有問題,就能有效的避免內(nèi)存泄漏;下面是我嘗試的方案,在工具類WebViewUtils.java里封裝好,在activity銷毀的時候調(diào)用

public static void release(WebView webView) {
        if (webView != null) {
            webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
            webView.stopLoading();
            ViewGroup parent = (ViewGroup) webView.getParent();
            if (parent != null) {
                parent.removeView(webView);
            }
            webView.clearHistory();
            webView.removeAllViews();
            webView.destroy();
        }
    }

    @Override
    public void onDestroy() {
        WebViewUtils.release(mWebView);
        super.onDestroy();
    }
2,加載白屏

由于白屏問題的出現(xiàn)的多樣性,暫提供多種嘗試性方案,大家按需參考

1,清除webview緩存和記錄

webview.clearCache(true);
webview.clearHistory();

2,可以設置不啟用緩存

websettings.setAppCacheEnabled(false);

3,H5的一些控件標簽不支持導致的白屏

websettings.setDomStorageEnabled(true);

4,xml啟用軟件加速

 <WebView
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layerType="software"
     android:scrollbars="none" />

5,通過menifest的來配置,在目標webview的activity設置

<activity
      android:name="xxx"
      android:hardwarAccelerated="false" />
3,安全&漏洞問題
  • Android 4.2前遠程代碼執(zhí)行漏洞的問題,又稱js注入

這個問題也是老生常談的問題,其原因是因為在API 17(Android 4.2)以前的系統(tǒng)版本,程序沒有正確限制使用addJavascriotInterface方法,遠程攻擊者可通過使用Java Reflection API利用該漏洞執(zhí)行任意Java對象的方法,可能出現(xiàn)手機被安裝木馬程序,發(fā)送扣費短信,通信錄或者短信被竊取,甚至手機被遠程控制等安全問題

解決方案:

1,設置minSdkVersion大于等于17,即不能再低于4.2的手機上運行
2,在需要被調(diào)用的Java方法上增加注解聲明:@JavascriptInterface

  • webview明文存儲密碼的問題

webview組建默認開啟了密碼保護功能,會提示用戶是否保存密碼,當用戶選擇保存后,用戶名和密碼會被以明文形式保存到應用數(shù)據(jù)目錄databases/webview.db中。攻擊者可能通過root的方式訪問該應用的WebView數(shù)據(jù)庫,從而竊取本地明文存儲的用戶名和密碼

解決方案:

調(diào)用webview.getSettings().setSavePassword(false);,讓webview不再存儲密碼

  • 有風險的系統(tǒng)隱藏接口問題

根據(jù)CVE披露的webview的遠程代碼執(zhí)行漏洞信息,Android系統(tǒng)中存在一共三個有遠程代碼執(zhí)行漏洞的隱藏接口。分別位于android/webkit/webview中的searchBoxJavaBridge接口,位于android/webkit/AccessibilityInjector的accessibility接口和accessibilityTraversal,調(diào)用此三個接口的APP在開啟輔助功能選項中第三方服務的Android系統(tǒng)上將面臨遠程代碼執(zhí)行漏洞

解決方案:

需要顯示移除這三個接口

webview.removeJavascriptInterface("xxx");


文章如有錯誤,煩請指出。此篇文章作為后續(xù)深入的基礎鋪墊,后面會再續(xù)寫webview的cookie設置和Android的數(shù)據(jù)交互等,敬請期待!

上一篇:Flutter入門-01-工程創(chuàng)建&目錄介紹

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容