先看原生和js相互调用的效果(如图,红线以上是webview展示的h5页面,红线以下是app的原生页面)
项目结构:
app需要用到的依赖:
//jsbridge
implementation 'com.github.lzyzsd:jsbridge:1.0.4'
MainActivity代码:
package com.shengqf.jsbridgedemo;
import android.content.Context;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.CallBackFunction;
public class MainActivity extends AppCompatActivity {
private BridgeWebView mWebView;
private EditText mEdt;
private Context mContext;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
initView();
setClick();
registerHandlers();
}
private void initView() {
mEdt = findViewById(R.id.edt);
initWebView();
}
private void initWebView() {
mWebView = findViewById(R.id.webView);
WebViewSettingUtil.initWebView(mWebView);
mWebView.loadUrl("file:///android_asset/web/index.html");
}
//注册js调用原生的方法
private void registerHandlers() {
mWebView.registerHandler("modifyAppEditValue", new BridgeHandler() {
//data是js传递给原生的数据,CallBackFunction是js的回调
@Override
public void handler(String data, CallBackFunction function) {
mEdt.setText(data);
function.onCallBack("app的输入框内容已被修改啦");
}
});
mWebView.registerHandler("clearAppEdt", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
mEdt.setText("");
function.onCallBack("app的输入框内容已被清空啦");
}
});
}
//原生调用js的方法
private void setClick() {
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String content = mEdt.getText().toString();
//原生调用js的方法(content是传递给js的数据)
mWebView.callHandler("modifyH5InputValue", content, new CallBackFunction() {
//原生调用完js方法后的回调(data是js回传给原生的数据)
@Override
public void onCallBack(String data) {
Toast.makeText(mContext, data, Toast.LENGTH_LONG).show();
}
});
}
});
findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//原生调用js的方法
mWebView.callHandler("clearH5Input", "", new CallBackFunction() {
//原生调用完js方法后的回调(data是js回传给原生的数据)
@Override
public void onCallBack(String data) {
Toast.makeText(mContext, data, Toast.LENGTH_LONG).show();
}
});
}
});
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (mWebView != null && mWebView.canGoBack()) {
mWebView.goBack();
return true;
} else {
System.exit(0);
}
}
return super.onKeyDown(keyCode, event);
}
}
WebViewSettingUtil的代码:
package com.shengqf.jsbridgedemo;
import android.annotation.SuppressLint;
import android.os.Build;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.BridgeWebViewClient;
import com.github.lzyzsd.jsbridge.DefaultHandler;
public class WebViewSettingUtil {
@SuppressLint("SetJavaScriptEnabled")
public static void initWebView(BridgeWebView webView) {
webView.setDefaultHandler(new DefaultHandler());
webView.setWebChromeClient(new WebChromeClient());
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new BridgeWebViewClient(webView));
// 如果不加这一行,当点击界面链接,跳转到外部时,会出现net::ERR_CACHE_MISS错误
if (Build.VERSION.SDK_INT >= 19) {
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
}
}
}
MainActivity的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.github.lzyzsd.jsbridge.BridgeWebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="240dp" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#f00" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp">
<EditText
android:id="@+id/edt"
android:layout_width="match_parent"
android:layout_height="44dp"
android:hint="请输入" />
<Button
android:id="@+id/btn1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="app输入框内容展示到h5输入框" />
<Button
android:id="@+id/btn2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="清空h5页面输入框内容" />
</LinearLayout>
</LinearLayout>
index.html:
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<title>page01</title>
<style type="text/css">
* {
padding: 0px;
margin: 0px;
}
.container {
padding: 20px;
}
.mt10{
margin-top: 10px;
}
</style>
</head>
<body>
<div class="container">
<div>
<input type="text" id="content" placeholder="请输入" />
</div>
<div class="mt10">
<input type="button" onclick="click1()" value="修改app里输入框内容" />
</div>
<div class="mt10">
<input type="button" onclick="click2()" value="清空app里输入框内容" />
</div>
</div>
<script>
//responseData为app回传给h5的数据
var callback = function(responseData) {
alert(responseData);
};
//修改app里输入框内容
function click1() {
console.log(123)
var content = document.getElementById("content").value;
//js调用app的方法
window.WebViewJavascriptBridge.callHandler(
'modifyAppEditValue', content, callback
);
}
//清空app里输入框内容
function click2() {
console.log(456)
//js调用app的方法
window.WebViewJavascriptBridge.callHandler(
'clearAppEdt', "", callback
);
}
//注册事件监听,监听app调用h5(这里只写了android的,ios的没写)
function setupWebViewJavascriptBridge(callback) {
//android使用
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady',
function() {
callback(WebViewJavascriptBridge)
},
false
);
}
}
// 注册回调函数,第一次连接时调用 初始化函数
setupWebViewJavascriptBridge(function(bridge) {
//初始化
bridge.init(function(message, responseCallback) {
var data = {
'Javascript Responds': 'Hello jarry!'
};
responseCallback(data);
});
//注册app调用js
bridge.registerHandler("modifyH5InputValue", function(data, responseCallback) {
var content = document.getElementById("content");
content.value = data;
var responseData = "h5页面输入框内容已被修改啦";
responseCallback(responseData);
});
//注册app调用js
bridge.registerHandler("clearH5Input", function(data, responseCallback) {
var content = document.getElementById("content");
content.value = "";
var responseData = "h5页面输入框内容已被清空啦";
responseCallback(responseData);
});
})
</script>
</body>
</html>
参考:https://www.jianshu.com/p/e37ccf32cb5b
参考:https://www.jianshu.com/p/910e058a1d63/