Android webview與js的數(shù)據(jù)交互
項(xiàng)目要用到Webview和js交互,查了查以前的項(xiàng)目感覺(jué)還是有必要整理下的。
簡(jiǎn)單描述下項(xiàng)目中用到的地方,比如說(shuō)在web頁(yè)需要用到登錄的地方點(diǎn)擊登錄跳轉(zhuǎn)到APP原生登錄界面去登錄,點(diǎn)擊web頁(yè)的撥打電話彈出原生dialog詢問(wèn)是否撥打,點(diǎn)擊web頁(yè)里面的圖片進(jìn)行放大處理。針對(duì)于上述的需求我們通用的方式大概有兩種,一是監(jiān)聽(tīng)a標(biāo)簽,在shouldOverrideUrlLoading根據(jù)URL進(jìn)行判斷,二是js代碼注入,找到我們想要處理的元素進(jìn)行js代碼注入。下面就這兩種方式簡(jiǎn)單的進(jìn)行描述
首先需要初始化WebView以及設(shè)置支持JavaScript,常用的配置屬性有一下幾種,可以在項(xiàng)目中根據(jù)需求添加
WebSettings webSetting = webView.getSettings();
// 支持JavaScript
webSetting.setJavaScriptEnabled(true);
// 設(shè)置可以訪問(wèn)文件s
webSetting.setAllowFileAccess(true);
// 告訴javascript來(lái)自動(dòng)打開(kāi)的窗口。這適用于JavaScript函數(shù)的窗口,open()。
webSetting.setJavaScriptCanOpenWindowsAutomatically(true);
// 支持縮放
webSetting.setSupportZoom(true);
// 是否禁止是網(wǎng)絡(luò)加載數(shù)據(jù)
webSetting.setBlockNetworkLoads(false);
// 設(shè)置是否支持多窗口
webSetting.setSupportMultipleWindows(true);
// 是否開(kāi)啟本地DOM存儲(chǔ)
webSetting.setDomStorageEnabled(true);
// 設(shè)置不緩存
webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);
// 阻塞加載圖片
webSetting.setBlockNetworkImage(false);
// 支持啟用插件
webSetting.setPluginState(WebSettings.PluginState.ON);
// 設(shè)置任意比較縮放為真
webSetting.setUseWideViewPort(true);
// 設(shè)置WebView加載頁(yè)面的模式
webSetting.setLoadWithOverviewMode(true);
// 控制頁(yè)面顯示布局
// NARROW_COLUMNS:可能的話使所有列的寬度不超過(guò)屏幕寬度
// NORMAL:正常顯示不做任何渲染
// SINGLE_COLUMN:把所有內(nèi)容放大webview等寬的一列中
webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
//禁止用地理定位
webSetting.setSaveFormData(true);
// 是否啟動(dòng)地理定位
webSetting.setGeolocationEnabled(true);
// 設(shè)置定位的數(shù)據(jù)庫(kù)路徑
webSetting.setGeolocationDatabasePath("/data/data/org.itri.html5webview/databases/");
接下來(lái)就是WebView交互中非常重要的兩個(gè)類WebViewClient和WebChromeClient。WebViewClient就是幫助WebView處理各種通知、請(qǐng)求事件的,具體來(lái)說(shuō)包括以下常用方法:
onLoadResource() // 在加載頁(yè)面資源時(shí)會(huì)調(diào)用,每一個(gè)資源(比如圖片)的加載都會(huì)調(diào)用一次。 shouldOverrideUrlLoading //在點(diǎn)擊請(qǐng)求的是鏈接是才會(huì)調(diào)用,重寫(xiě)此方法返回true表明點(diǎn)擊網(wǎng)頁(yè)里面的鏈接還是在當(dāng)前的webview里跳轉(zhuǎn),不跳到瀏覽器那邊。這個(gè)函數(shù)我們可以做很多操作,比如我們讀取到某些特殊的URL,于是就可以不打開(kāi)地址,取消這個(gè)操作,進(jìn)行預(yù)先定義的其他操作,這對(duì)一個(gè)程序是非常必要的。 onPageStart //這個(gè)事件就是開(kāi)始載入頁(yè)面調(diào)用的,通常我們可以在這設(shè)定一個(gè)loading的頁(yè)面,告訴用戶程序在等待網(wǎng)絡(luò)響應(yīng)。 onPageFinish //在頁(yè)面加載結(jié)束時(shí)調(diào)用。同樣道理,我們知道一個(gè)頁(yè)面載入完成,于是我們可以關(guān)閉loading 條,切換程序動(dòng)作。 onReceiveError // (報(bào)告錯(cuò)誤信息) onReceivedHttpAuthRequest ()//(獲取返回信息授權(quán)請(qǐng)求)
WebChromeClient是輔助WebView處理Javascript的對(duì)話框,網(wǎng)站圖標(biāo),網(wǎng)站title,加載進(jìn)度等 ,常用方法有以下幾個(gè):
onCloseWindow() //關(guān)閉WebView onCreateWindow() onJsAlert //WebView上alert是彈不出來(lái)東西的,需要定制你的WebChromeClient處理彈出) onJsPrompt onJsConfirm onProgressChanged //可以根據(jù)加載進(jìn)度設(shè)置進(jìn)度條 onReceivedIcon //可以獲取URL icon onReceivedTitle //可以獲取URL title
一、監(jiān)聽(tīng)a標(biāo)簽
這種實(shí)現(xiàn)方式比較簡(jiǎn)單,我們可以在shouldOverrideUrlLoading中根據(jù)URL進(jìn)行判斷,比如說(shuō)界面中有一個(gè)撥打電話的功能,其js代碼如下

這里我們可以通過(guò)如下方式進(jìn)行彈出原生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;
}
二、通過(guò)js代碼
查了下常用的注入方式有兩種,第一種是當(dāng)webview加載完之后,讀取整個(gè)js文件中的內(nèi)容,然后將整個(gè)文件內(nèi)容以字符串的形式,通過(guò)webview.loadUrl(“javascript:fileContentString”)注入,不過(guò)我好像沒(méi)怎么用到過(guò)這個(gè)方式,一般都是用第二種,即通過(guò)給特定標(biāo)簽設(shè)置事件來(lái)滿足業(yè)務(wù)需求。
比如說(shuō)我們給所有的圖片設(shè)置一個(gè)點(diǎn)擊事件來(lái)獲取圖片,進(jìn)行一些列放大存儲(chǔ)等操作,我們可以通過(guò)如下代碼來(lái)實(shí)現(xiàn)。
// 注入js函數(shù)監(jiān)聽(tīng)
private void addImageClickListner() {
// 這段js函數(shù)的功能就是,遍歷所有的img幾點(diǎn),并添加onclick函數(shù),函數(shù)的功能是在圖片點(diǎn)擊的時(shí)候調(diào)用本地java接口并傳遞url過(guò)去
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();
}
}
//上述兩個(gè)方法實(shí)現(xiàn)了給圖片添加點(diǎn)擊事件,我們還需要對(duì)webview進(jìn)行設(shè)置以及注入
@SuppressLint({"JavascriptInterface", "NewApi"})
@Override
public void onPageFinished(WebView view, String url) {
view.getSettings().setJavaScriptEnabled(true);
super.onPageFinished(view, url);
addImageClickListner();// 頁(yè)面加載完成之后,添加監(jiān)聽(tīng)圖片的點(diǎn)擊js函數(shù)
}
//對(duì)WebView進(jìn)行設(shè)置
webView.addJavascriptInterface(new JavascriptInterface(this), "imagelistner");
上述實(shí)現(xiàn)方式有以下幾點(diǎn)需要注意:1、注意這里的方法名imagelistener要和輸入的js代碼里面的方法一致,2、自定義的方法openImage一定要注明@Android.webkit.JavascriptInterface,否則不起作用。
可以看到我們注入的js代碼是通過(guò)getElementsByTagName獲取所有的img元素然后設(shè)置點(diǎn)擊事件,如果我們相對(duì)某一特定的元素進(jìn)行設(shè)置也可以通過(guò)getElementById獲取單獨(dú)的元素,或者還可以通過(guò)getElementsByTagName根據(jù)TAG獲取元素。
這是我現(xiàn)階段知道的方式,如果還有其它比較好的實(shí)現(xiàn)方式可以一起討論下。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android開(kāi)發(fā)實(shí)現(xiàn)在TextView前面加標(biāo)簽示例
這篇文章主要為大家介紹了Android開(kāi)發(fā)實(shí)現(xiàn)TextView前面加標(biāo)簽示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
Android RecyclerView使用入門(mén)介紹
RecyclerView是Android一個(gè)更強(qiáng)大的控件,其不僅可以實(shí)現(xiàn)和ListView同樣的效果,還有優(yōu)化了ListView中的各種不足。其可以實(shí)現(xiàn)數(shù)據(jù)縱向滾動(dòng),也可以實(shí)現(xiàn)橫向滾動(dòng)(ListView做不到橫向滾動(dòng))。接下來(lái)講解RecyclerView的用法2022-10-10
Android改變ExpandableListView的indicator圖標(biāo)實(shí)現(xiàn)方法
這篇文章主要介紹了Android改變ExpandableListView的indicator圖標(biāo)實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了改變ExpandableListView的indicator圖標(biāo)相關(guān)步驟與實(shí)現(xiàn)技巧,涉及Android配置文件的修改,需要的朋友可以參考下2016-03-03
Android實(shí)現(xiàn)手勢(shì)滑動(dòng)多點(diǎn)觸摸放大縮小圖片效果
這篇文章主要介紹了Android實(shí)現(xiàn)手勢(shì)滑動(dòng)多點(diǎn)觸摸放大縮小圖片效果的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-02-02
Android實(shí)現(xiàn)微信自動(dòng)向附近的人打招呼(AccessibilityService)
這篇文章主要為大家詳細(xì)介紹了實(shí)現(xiàn)微信自動(dòng)向附近的人打招呼,實(shí)現(xiàn)收到指定賬戶推送文章時(shí)自動(dòng)進(jìn)入微信打開(kāi)鏈接,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
Kotlin類的繼承實(shí)現(xiàn)詳細(xì)介紹
這篇文章主要介紹了Kotlin類的繼承,在Java中類的繼承默認(rèn)是繼承父類的方法和參數(shù)的,但是在kotlin中默認(rèn)是不繼承的,那么我們接下來(lái)來(lái)驗(yàn)證2022-09-09

