Android与Js交互之JSBridge的使用
什么是JsBridge
JsBridge是js与Native之间进行通信的桥梁。
为什么要使用JsBridge
Android4.2以下的addJavascriptInterface存在安全漏洞,虽然在Android4.2之后用@JavascriptInterface代替了addJavascriptInterface但是由于兼容性和安全性问题,基本上我们不会再利用Android系统为我们提供的addJavascriptInterface方法或者@JavascriptInterface注解来实现,所以我们只能另辟蹊径,去寻找既安全,又能实现兼容Android各个版本的方案。
如何使用JsBridge
在Android中我们使用JsBridge开源项目来实现,实现JSBridge分为以下几个步骤。
步骤一:导入依赖
在项目gradle文件中添加
repositories {
...
maven { url "https://jitpack.io" }
}
在module的gradle中添加
dependencies {
...
implementation 'com.github.lzyzsd:jsbridge:1.0.4'
}
步骤二:布局文件中用BridgeWebView代替WebView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity">
<EditText
android:layout_width="match_parent"
android:id="@+id/et"
android:layout_height="wrap_content" />
<Button
android:layout_width="match_parent"
android:text="调用js方法"
android:id="@+id/bt"
android:layout_height="wrap_content" />
<com.github.lzyzsd.jsbridge.BridgeWebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.github.lzyzsd.jsbridge.BridgeWebView>
</LinearLayout>
步骤三:在Activity中对BridgeWebView进行配置
public class MainActivity extends AppCompatActivity {
private EditText et;
private Button bt;
private BridgeWebView webview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = (EditText) findViewById(R.id.et);
bt = (Button) findViewById(R.id.bt);
webview = (BridgeWebView) findViewById(R.id.webview);
webview.setDefaultHandler(new DefaultHandler());
webview.setWebChromeClient(new WebChromeClient());
webview.loadUrl("file:///android_asset/test.html");
// 注册监听方法当js中调用callHandler方法时会调用此方法(handlerName必须和js中相同)
webview.registerHandler("submitFromWeb", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
Log.e("TAG", "js返回:" + data);
//显示js传递给Android的消息
Toast.makeText(MainActivity.this, "js返回:" + data, Toast.LENGTH_LONG).show();
//Android返回给JS的消息
function.onCallBack("我是js调用Android返回数据:" + et.getText().toString());
}
});
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 调用js中的方法(必须和js中的handlerName想同)
webview.callHandler("functionInJs", "Android调用js66", new CallBackFunction() {
@Override
public void onCallBack(String data) {
Log.e("TAG", "onCallBack:" + data);
Toast.makeText(MainActivity.this, data, Toast.LENGTH_LONG).show();
}
});
}
});
}
}
步骤四:编写html文件并对应Activity中的参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="./materialize.min.css">
<!-- Compiled and minified JavaScript -->
<script src="./materialize.min.js"></script>
<title>Test</title>
</head>
<body>
<div class="input-field col s6">
<input placeholder="请输入数据" id="text1" type="text" class="validate">
</div>
<a class="waves-effect waves-light btn" onclick="testClick();">button</a>
</body>
<script>
//js调用Android方法:接收Android传递过来的数据,并做处理
function testClick() {
//参数一:调用java中的方法 submitFromWeb是方法名,必须和Android中注册时候的方法名称保持一致
//参数二:返回给Android端的数据,可以为字符串,json等信息
//参数三:js接收到Android传递过来的数据之后的相应处理逻辑
window.WebViewJavascriptBridge.callHandler(
'submitFromWeb'
, {'param': "JS成功接收到数据---"}
, function(responseData) {
alert(responseData)
}
);
}
//JS注册事件监听
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady'
, function() {
callback(WebViewJavascriptBridge)
},
false
);
}
}
//注册回调函数,第一次连接时调用 初始化函数
connectWebViewJavascriptBridge(function(bridge) {
//初始化
bridge.init(function(message, responseCallback) {
var data = {
'Javascript Responds': 'Wee!'
};
alert("jasdashjd");
responseCallback(data);
});
//Android调用js方法:functionInJs方法名称需要保持一致 ,并返回给Android通知
bridge.registerHandler("functionInJs", function(data, responseCallback) {
alert(data);
var data2 = document.getElementById("text1").value;
var responseData = "我是Android调用js方法返回的数据---"+ data2;
responseCallback(responseData);
});
})
</script>
</html>
步骤五:将html文件放入assets文件夹中
效果展示:
补充:
jsbridge调用默认的方法
●Activity代码
// 重写handler方法接收js的消息
webview.setDefaultHandler(new DefaultHandler(){
@Override
public void handler(String data, CallBackFunction function) {
Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
function.onCallBack("Android收到了默认的消息");
}
});
bt2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 发送信息给js,此处不需要配置handlerName
webview.send(et.getText().toString().trim(), new CallBackFunction() {
@Override
public void onCallBack(String data) {
// 接收js的回调数据
Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();
}
});
}
});
●html代码
//初始化
bridge.init(function(message, responseCallback) {
var data = {
'Javascript Responds': 'Wee!'
};
//添加代码用来弹出Activity发送的默认消息
alert(message);
responseCallback(data);
});
// 加入如下方法用于发送消息给Activity
function testClick2() {
var data2 = document.getElementById("text1").value;
//参数一:调用java中的方法 submitFromWeb是方法名,必须和Android中注册时候的方法名称保持一致
//参数二:返回给Android端的数据,可以为字符串,json等信息
//参数三:js接收到Android传递过来的数据之后的相应处理逻辑
window.WebViewJavascriptBridge.send(
data2,
function(responseData){
//java中DefaultHandler所实现的方法中callback所定义的入参
alert(responseData);
}
);
}
案例源码

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
4-SII--☆Android缓存文件(带有效时长)封装
零、前言 [1]把我的缓存文件工具改写成了策略模式,感觉还不错。 [2]以前静态方法调用,很方便,但看着就是不爽,代码真的太冗余了。 [3]突然灵光一闪,"少年,看你骨骼惊奇,策略模式了解一下吗。"便有此文。 [4]如果不了解SharedPreferences,可以先看这篇:1-SII--SharedPreferences完美封装 缓存策略类图 缓存策略.png 一、使用: //新建缓存对象 CacheWorker innerCache = new CacheWorker(new InnerFileStrategy(this)); //设置缓存 innerCache.setCache("toly", "hehe", 10); //获取缓存 String value = innerCache.getCache("toly"); //SD卡缓存 CacheWorker sdCache = new CacheWorker(new SDFileStrategy()); sdCache.setCache("toly", "hehe2", 10); String sdCach = sdCache....
-
下一篇
Gradle 使用技巧(五) - AAR
1. 什么是AAR 关于aar文件,摘取官方的解释:AAR 文件的文件扩展名为 .aar,Maven 工件类型也应当是 aar。文件本身是一个包含以下强制性条目的 zip 文件: /AndroidManifest.xml /classes.jar /res/ /R.txt 此外,AAR 文件可能包含以下可选条目中的一个或多个: /assets/ /libs/名称.jar /jni/abi 名称/名称.so(其中 abi 名称 是 Android 支持的 ABI 之一) /proguard.txt /lint.jar 2. AAR文件位置 AAP的位置为 【项目名称/模块名称/build/outputs/aar/】 中,如果没有aar文件,可以通过点击 Build > Make Project 的方式重新生成此文件。 需要注意的是:只有library模块才会生成aar文件,application模块是不会生成的。 3. 如何使用AAR文件 创建一个library工程,写一段简单的代码。 TestUtils Build -> Make Project aar文件位置 将aar文...
相关文章
文章评论
共有0条评论来说两句吧...