Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

2 Commits

Repository files navigation

AndroidJSInterface

此项目,主要演示Android的WebView视图中,Native Call JavaScript、以及JavaScript Call Native的几种方式。


写在前面: Hybrid不可避免使用Native和JS交互,本文主要总结一下Android和JavaScript交互的解决方方。

[TOC]

A、Native调用JavaScript

方案一:调用loadUrl执行一段js
mWebView.loadUrl("javascript:alert('hello world')");
方案二:调用evaluateJavascript异步执行一段js
StringjsString = "sum(a, b)";
mWebView.evaluateJavascript(js, newValueCallback<String>() {
@OverridepublicvoidonReceiveValue(Strings) {
// 这里可以处理被调用js方法的return
}
});
方案三:引用JsBridge框架
  • Web首先初始化WebViewJavascriptBridge,注册事件监听。
  • Web然后初始化接收函数回调,分为默认接收指定接收,responseCallback回调给Native信息
  • Native 调用Webview.send()WebView.callHandler()
//注册事件监听,初始化functionsetupWebViewJavascriptBridge(callback){if(window.WebViewJavascriptBridge){callback(WebViewJavascriptBridge)}else{document.addEventListener('WebViewJavascriptBridgeReady',function(){callback(WebViewJavascriptBridge)},false);}}//回调函数,接收java发送来的数据setupWebViewJavascriptBridge(function(bridge){//默认接收bridge.init(function(message,responseCallback){// 处理接收到消息});//指定接收,bridge.registerHandler("JSFUCN",function(data,responseCallback){// 处理接收到消息});})
// 默认接收privatevoidcallJavaScriptDefaut() {
mWebView.send("发送数据给js默认接收, new CallBackFunction() { @Override public void onCallBack(String data) { //处理js回传的数据 }); } // 指定接收 private void callJavaScriptSpec() { mWebView.callHandler("JSFUCN", "发送数据给js指定接收", newCallBackFunction() {
@OverridepublicvoidonCallBack(Stringdata) { //处理js回传的数据
}
});
}

利用 webview调用js需要注意一下几点

  • WebSettings设置支持javascript
// 设置在类之前@SuppressLint("SetJavaScriptEnabled") mWebView.getSettings().setJavaScriptEnabled(true);
  • 在运行Js脚本前,要有document对象,至少得load一个空白页
webView.loadData("","text/html","UTF-8");
  • 如果还是不行的话,就应该是因为第一个还没执行完呢 - 从界面按钮调用 - 延时调用 - 在onPageFinished中调用
webView.loadData(“”,"text/html","UTF-8");
webView.loadUrl("javascript:alert('hello')");
  • 必须实现WebChromeClient、WebViewClient
webView.setWebViewClient(newWebViewClient());
webView.setWebChromeClient(newWebChromeClient());
  • 使用JSBridge不用实现WebViewClient

B、JavaScript调用Native

方案一:拦截跳转
  • WebViewClient重载shouldOverrideUrlLoading 拦截URL

Web代码

functionopenMyBlogNewTarget(){window.open('https://www.jianshu.com/u/263c210b047c')}functionopenMyBlog(){window.location.href='https://www.jianshu.com/u/263c210b047c'}
<ahref="http://www.baidu.com" title="baidu" target="_blank">新标签页打开百度</a><ahref="http://www.baidu.com" title="baidu" >当前页打开百度</a><buttononclick='openMyBlogNewTarget()'>新标签打开我的博客</button><buttononclick="openMyBlog()">打开我的博客</button>

Android代码

privateclassMYWebViewClientextendsWebViewClient {
@OverridepublicvoidonPageStarted(WebViewview, Stringurl, Bitmapfavicon) {
super.onPageStarted(view, url, favicon);
}
// 新方法 API21以后@OverridepublicbooleanshouldOverrideUrlLoading(WebViewview, WebResourceRequestrequest) {
super.shouldOverrideUrlLoading(view, request);
// 拦截Requestif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Log.d(TAG, "shouldOverrideUrlLoading: " + request.getUrl().toString());
}
returntrue;
}
// 旧方法 兼容API21之前@OverridepublicbooleanshouldOverrideUrlLoading(WebViewview, Stringurl) {
super.shouldOverrideUrlLoading(view, url);
// 拦截urlLog.d(TAG, "shouldOverrideUrlLoading: " + url);
returntrue;
}
}
方案二:JSInterface
  • JS中使用window.objects.function语法调用Native,其中objects与Native中一直。
  • Native中定义Class,以及被调用的func用 public、@JavascriptInterface修饰。
  • Native中addJavascriptInterface(obj, name)
functioncallNative(){varamount=123.5;varorderno="FG1afsdakewqr";window.mobileApp.toPay(amount,orderno);}
<buttononclick="window.mobileApp.sendMessage('特斯拉 Model 3')">获取商品名</button><buttononclick="callNative()">支付按钮</button>
mWebView.addJavascriptInterface(newJsInterface(tv), "mobileApp");
privateclassJsInterface {
privateTextViewshowText;
publicJsInterface(TextViewtv) {
showText = tv;
}
@JavascriptInterfacepublicvoidsendMessage(Stringmsg) {
Log.d(TAG, "sendMessage: " + msg);
}
@JavascriptInterfacepublicvoidtoPay(floatamount, Stringoderno) {
Log.d(TAG, "sendMessage: " + amount);
}
}
方案三:引用JsBridge框架
  • JS中调用window.WebViewJavascriptBridge.send 或者 window.WebViewJavascriptBridge.callHandler 向Native发消息
  • Native中注册指定接收WebView.registerHandler或者注册默认接收WebView.setDefaultHandler
//js传递数据给javafunctionjsCallNativeDefault(){window.WebViewJavascriptBridge.send({'param': "str1"},function(responseData){//处理java回传的数据});}functionjsCallNativeSpec(){window.WebViewJavascriptBridge.callHandler('Spec'//指定接收参数 submitFromWeb与java一致,'指定接收',function(responseData){//处理java回传的数据});}
mWebView.registerHandler("Spec", newBridgeHandler() {
@Overridepublicvoidhandler(Stringdata, CallBackFunctionfunction) {
Log.i("", "handler = submitFromWeb, data from web = " + data);
function.onCallBack("submitFromWeb exe, response data 中文 from Java");
showTextView.setText("指定接收:" + data);
}
});
mWebView.setDefaultHandler(newDefaultHandler() {
@Overridepublicvoidhandler(Stringdata, CallBackFunctionfunction) {
Log.i("", "handler = submitFromWeb, data from web = " + data);
function.onCallBack("submitFromWeb exe, response data 中文 from Java");
showTextView.setText("默认接收:" + data);
}
});

About

此项目,主要演示Android的WebView视图中,Native Call JavaScript、以及JavaScript Call Native的几种方式。

Topics

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages