Android中webview與JS交互、互調(diào)方法實例詳解
創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、留壩網(wǎng)絡(luò)推廣、成都小程序開發(fā)、留壩網(wǎng)絡(luò)營銷、留壩企業(yè)策劃、留壩品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;創(chuàng)新互聯(lián)公司為所有大學生創(chuàng)業(yè)者提供留壩建站搭建服務(wù),24小時服務(wù)熱線:028-86922220,官方網(wǎng)址:www.cdcxhl.com
前言:
對于試水的功能,一般公司都會采用H5的方式來開發(fā),可以用很少的資源與很短的項目工期來完成。
但許多情況下,H5頁面會需要一些原生持有的一些如用戶信息之類的數(shù)據(jù),一些交互也需要調(diào)用原生的,如toast之類要保持同一個手機風格一致的交互行為。這個時候就需要能夠讓JS主動調(diào)用原生的方法來進行操作或者獲取數(shù)據(jù)?;蛘呤窃{(diào)用JS的方法在H5加載的時候傳遞一些參數(shù)。
對于原生調(diào)用JS的方法
我們需要實現(xiàn)一個WebViewClient,在這個WebViewClient里面進行JS方法加載的替換
如
webView_.setWebViewClient(new WebViewClient() { public void onPageFinished(WebView view, String url) { view.loadUrl(MessageFormat.format("javascript:initEvaluationPage({0})", Util.wrapGetParameter(json) )); } });
這里的initEvaluationPage必須要和JS的方法名一致
建議傳遞json格式數(shù)據(jù)作為參數(shù)。
不要忘了允許WebView執(zhí)行JS代碼
webView_.getSettings()s.setJavaScriptEnabled(true);
對于JS調(diào)用原生方法,稍微復(fù)雜一些
首先,需要本地定義一個接口,接口名需要和JS內(nèi)寫的一致
比如JS需要客戶端保存的用戶信息
JS中代碼是這樣的
var userInfo = JSON.parse(window.JSUserInfoInterface.getUserInfo());
那么我們本地也需要定義一個對應(yīng)的接口
public interface JSUserInfoInterface { @JavascriptInterface String getUserInfo(); }
接口名方法名一致
實例化這個接口,在實例方法內(nèi)返回我們的用戶信息
JSUserInfoInterface method3 = new JSUserInfoInterface() { @Override @JavascriptInterface public String getUserInfo() { SharedPreferences sharedPreferences = getActivity().getApplicationContext().getSharedPreferences( "share", Context.MODE_PRIVATE); String tel = sharedPreferences.getString(Constant.KEY_USERNAME, ""); String userid = sharedPreferences.getString("userid", ""); return "{\"user_id\":\"" + userid + "\",\"user_tel\":\"" + tel + "\"}"; } };
注意不能忘了 @JavascriptInterface注解
然后將這個接口方法加入到webView_中,注意第二個參數(shù)就是接口名,需要和JS中的一致。
webView_.addJavascriptInterface(method3, "JSUserInfoInterface");
這樣就可以在JS調(diào)用window.JSUserInfoInterface.getUserInfo()的時候返回我們實例里面給的數(shù)據(jù)
同樣的,我們也可以不返回數(shù)據(jù)直接執(zhí)行。比如彈一個原生的Dialog。
需要注意的是JS里面是沒有主線程子線程的概念的,當JS進行網(wǎng)絡(luò)請求的時候,webview會默認給他開子線程。具體機制大家感興趣可以去了解。不過這也就意味著你不能直接在給JS掉的原生方法中進行UI操作。你可以選擇發(fā)送給主線程執(zhí)行。
比如下面的代碼我是用rxjava來切換線程的
JSDialogInterface method2 = new JSDialogInterface() { @Override @JavascriptInterface public void changeDialog(String arg0) { Observable.just(arg0) .observeOn(AndroidSchedulers.mainThread()) .subscribe(mess -> { if (mess.equals("show")) { ld_.show(); } else { ld_.dismiss(); } }); } };
最后
一點小建議
如果你的項目中有很多或者一定數(shù)量的JS交互,建議寫一個有返回值的接口。然后通過JSON參數(shù)來進行控制。內(nèi)部制定一個解析協(xié)議,根據(jù)JSON的數(shù)據(jù)來決定要做什么事,避免大量定義接口 ,也避免構(gòu)建太多的實例消耗資源
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!