Android webview與js的數(shù)據(jù)交互
項目要用到Webview和js交互,查了查以前的項目感覺還是有必要整理下的。
簡單描述下項目中用到的地方,比如說在web頁需要用到登錄的地方點擊登錄跳轉(zhuǎn)到APP原生登錄界面去登錄,點擊web頁的撥打電話彈出原生dialog詢問是否撥打,點擊web頁里面的圖片進行放大處理。針對于上述的需求我們通用的方式大概有兩種,一是監(jiān)聽a標簽,在shouldOverrideUrlLoading根據(jù)URL進行判斷,二是js代碼注入,找到我們想要處理的元素進行js代碼注入。下面就這兩種方式簡單的進行描述
首先需要初始化WebView以及設(shè)置支持JavaScript,常用的配置屬性有一下幾種,可以在項目中根據(jù)需求添加
WebSettings webSetting = webView.getSettings(); // 支持JavaScript webSetting.setJavaScriptEnabled(true); // 設(shè)置可以訪問文件s webSetting.setAllowFileAccess(true); // 告訴javascript來自動打開的窗口。這適用于JavaScript函數(shù)的窗口,open()。 webSetting.setJavaScriptCanOpenWindowsAutomatically(true); // 支持縮放 webSetting.setSupportZoom(true); // 是否禁止是網(wǎng)絡(luò)加載數(shù)據(jù) webSetting.setBlockNetworkLoads(false); // 設(shè)置是否支持多窗口 webSetting.setSupportMultipleWindows(true); // 是否開啟本地DOM存儲 webSetting.setDomStorageEnabled(true); // 設(shè)置不緩存 webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE); // 阻塞加載圖片 webSetting.setBlockNetworkImage(false); // 支持啟用插件 webSetting.setPluginState(WebSettings.PluginState.ON); // 設(shè)置任意比較縮放為真 webSetting.setUseWideViewPort(true); // 設(shè)置WebView加載頁面的模式 webSetting.setLoadWithOverviewMode(true); // 控制頁面顯示布局 // NARROW_COLUMNS:可能的話使所有列的寬度不超過屏幕寬度 // NORMAL:正常顯示不做任何渲染 // SINGLE_COLUMN:把所有內(nèi)容放大webview等寬的一列中 webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); //禁止用地理定位 webSetting.setSaveFormData(true); // 是否啟動地理定位 webSetting.setGeolocationEnabled(true); // 設(shè)置定位的數(shù)據(jù)庫路徑 webSetting.setGeolocationDatabasePath("/data/data/org.itri.html5webview/databases/");
接下來就是WebView交互中非常重要的兩個類WebViewClient和WebChromeClient。WebViewClient就是幫助WebView處理各種通知、請求事件的,具體來說包括以下常用方法:
onLoadResource() // 在加載頁面資源時會調(diào)用,每一個資源(比如圖片)的加載都會調(diào)用一次。 shouldOverrideUrlLoading //在點擊請求的是鏈接是才會調(diào)用,重寫此方法返回true表明點擊網(wǎng)頁里面的鏈接還是在當(dāng)前的webview里跳轉(zhuǎn),不跳到瀏覽器那邊。這個函數(shù)我們可以做很多操作,比如我們讀取到某些特殊的URL,于是就可以不打開地址,取消這個操作,進行預(yù)先定義的其他操作,這對一個程序是非常必要的。 onPageStart //這個事件就是開始載入頁面調(diào)用的,通常我們可以在這設(shè)定一個loading的頁面,告訴用戶程序在等待網(wǎng)絡(luò)響應(yīng)。 onPageFinish //在頁面加載結(jié)束時調(diào)用。同樣道理,我們知道一個頁面載入完成,于是我們可以關(guān)閉loading 條,切換程序動作。 onReceiveError // (報告錯誤信息) onReceivedHttpAuthRequest ()//(獲取返回信息授權(quán)請求)
WebChromeClient是輔助WebView處理Javascript的對話框,網(wǎng)站圖標,網(wǎng)站title,加載進度等 ,常用方法有以下幾個:
onCloseWindow() //關(guān)閉WebView onCreateWindow() onJsAlert //WebView上alert是彈不出來東西的,需要定制你的WebChromeClient處理彈出) onJsPrompt onJsConfirm onProgressChanged //可以根據(jù)加載進度設(shè)置進度條 onReceivedIcon //可以獲取URL icon onReceivedTitle //可以獲取URL title
一、監(jiān)聽a標簽
這種實現(xiàn)方式比較簡單,我們可以在shouldOverrideUrlLoading中根據(jù)URL進行判斷,比如說界面中有一個撥打電話的功能,其js代碼如下
這里我們可以通過如下方式進行彈出原生dialog
public boolean shouldOverrideUrlLoading(WebView view, String url) { if (TextUtils.isEmpty(url)) return true; if (url.startsWith("tel:")) { PhoneDialog callDialog = new PhoneDialog(WebViewActivity.this, url); callDialog.disDialog(); callDialog.callPhone(); callDialog.show(); return true; } return true; }
二、通過js代碼
查了下常用的注入方式有兩種,第一種是當(dāng)webview加載完之后,讀取整個js文件中的內(nèi)容,然后將整個文件內(nèi)容以字符串的形式,通過webview.loadUrl(“javascript:fileContentString”)注入,不過我好像沒怎么用到過這個方式,一般都是用第二種,即通過給特定標簽設(shè)置事件來滿足業(yè)務(wù)需求。
比如說我們給所有的圖片設(shè)置一個點擊事件來獲取圖片,進行一些列放大存儲等操作,我們可以通過如下代碼來實現(xiàn)。
// 注入js函數(shù)監(jiān)聽 private void addImageClickListner() { // 這段js函數(shù)的功能就是,遍歷所有的img幾點,并添加onclick函數(shù),函數(shù)的功能是在圖片點擊的時候調(diào)用本地java接口并傳遞url過去 webView.loadUrl("javascript:(function(){" + "var objs = document.getElementsByTagName(\"img\"); " + "for(var i=0;i<objs.length;i++) " + "{" + " objs[i].onclick=function() " + " { " + " window.imagelistner.openImage(this.src); " + " } " + "}" + "})()"); } // js通信接口 public class JavascriptInterface { private Context context; public JavascriptInterface(Context context) { this.context = context; } @android.webkit.JavascriptInterface public void openImage(String img) { Toast.makeText(context,img,Toast.LENGTH_SHORT).show(); } } //上述兩個方法實現(xiàn)了給圖片添加點擊事件,我們還需要對webview進行設(shè)置以及注入 @SuppressLint({"JavascriptInterface", "NewApi"}) @Override public void onPageFinished(WebView view, String url) { view.getSettings().setJavaScriptEnabled(true); super.onPageFinished(view, url); addImageClickListner();// 頁面加載完成之后,添加監(jiān)聽圖片的點擊js函數(shù) } //對WebView進行設(shè)置 webView.addJavascriptInterface(new JavascriptInterface(this), "imagelistner");
上述實現(xiàn)方式有以下幾點需要注意:1、注意這里的方法名imagelistener要和輸入的js代碼里面的方法一致,2、自定義的方法openImage一定要注明@Android.webkit.JavascriptInterface,否則不起作用。
可以看到我們注入的js代碼是通過getElementsByTagName獲取所有的img元素然后設(shè)置點擊事件,如果我們相對某一特定的元素進行設(shè)置也可以通過getElementById獲取單獨的元素,或者還可以通過getElementsByTagName根據(jù)TAG獲取元素。
這是我現(xiàn)階段知道的方式,如果還有其它比較好的實現(xiàn)方式可以一起討論下。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android開發(fā)實現(xiàn)在TextView前面加標簽示例
這篇文章主要為大家介紹了Android開發(fā)實現(xiàn)TextView前面加標簽示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-04-04Android改變ExpandableListView的indicator圖標實現(xiàn)方法
這篇文章主要介紹了Android改變ExpandableListView的indicator圖標實現(xiàn)方法,結(jié)合實例形式分析了改變ExpandableListView的indicator圖標相關(guān)步驟與實現(xiàn)技巧,涉及Android配置文件的修改,需要的朋友可以參考下2016-03-03Android實現(xiàn)手勢滑動多點觸摸放大縮小圖片效果
這篇文章主要介紹了Android實現(xiàn)手勢滑動多點觸摸放大縮小圖片效果的相關(guān)資料,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-02-02Android實現(xiàn)微信自動向附近的人打招呼(AccessibilityService)
這篇文章主要為大家詳細介紹了實現(xiàn)微信自動向附近的人打招呼,實現(xiàn)收到指定賬戶推送文章時自動進入微信打開鏈接,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-12-12