大家好,欢迎来到IT知识分享网。
Android开发中,由于Android系统的碎片化比较严重,开发者多数时间放在UI的适配上,使用原生控件开发耗时耗力,而且在实现复杂界面时,原生控件的布局能力较弱,一种常见的方案是使用H5来负责复杂界面的布局,用Android提供的原生控件WebView进行加载,但界面和系统的逻辑交互以及数据交换,又成为了一个问题,JsBridge的诞生正好解决了这一难题。
1,JsBridge基本概念
Android4.4以前,谷歌的webview存在安全漏洞,网站可以通过js注入就可以随便拿到客户端的重要信息,甚至轻而易举的调用本地代码进行流氓行为,谷歌在4.4以后增加了防御措施,如果用js调用本地代码,开发者必须在代码声明JavascriptInterface, 4.0之前我们要使得webView加载js只需如下代码:
mWebView.addJavascriptInterface(new JsToJava(), “myjsfunction”);
4.4之后使用时, 需要在调用Java方法加入@JavascriptInterface注解,如果代码无此声明,那么js就不生效,这样就可以避免恶意网页利用js对客户端的进行窃取和攻击。 但使用比较繁琐,要做一些判断和限制,在比较复杂的Hybrid模式下,需要js和native之间进行交互通讯,原生的JavascriptInterface 难以维护,基于JavascriptInterface 封装的WebViewJavascriptBridge框架,很好的解决了这一问题。
WebViewJavascriptBridge是移动UIView和Html交互通信的桥梁,用于替代WebView自带的JavascriptInterface接口,使开发者可以简单安全的实现js和native交互。
2,使用方法
在Android studio中,首先引入资源:
repositories {
maven { url "https://jitpack.io" }
}
dependencies {
compile 'com.github.lzyzsd:jsbridge:1.0.4'
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
主界面:
package com.win.jsbridgetest;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.widget.Button;
import android.widget.Toast;
import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.github.lzyzsd.jsbridge.DefaultHandler;
/** * Created by hzk on 2017/3/13. */
public class JsTestActivity extends AppCompatActivity {
BridgeWebView bridgeWebView;
Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.jsbridge_layout);
getSupportActionBar().setTitle("JsBridge_test");
button = (Button) findViewById(R.id.button3);
bridgeWebView = (BridgeWebView) findViewById(R.id.JsBridgeWebView);
bridgeWebView.setDefaultHandler(new DefaultHandler());
bridgeWebView.setWebChromeClient(new WebChromeClient());
bridgeWebView.getSettings().setJavaScriptEnabled(true);
bridgeWebView.setWebViewClient( new MyWebViewClient(bridgeWebView));
// 如果不加这一行,当点击界面链接,跳转到外部时,会出现net::ERR_CACHE_MISS错误
// 需要在androidManifest.xml文件中声明联网权限
// <uses-permission android:name="android.permission.INTERNET"/>
if (Build.VERSION.SDK_INT >= 19) {
bridgeWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
}
bridgeWebView.loadUrl("file:///android_asset/test.html");
/** * 前端发送消息给客户端 submitFromWeb 是js调用的方法名 安卓返回给js */
bridgeWebView.registerHandler("submitFromWeb", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
//显示接收的消息
showToast(data);
//返回给html的消息
function.onCallBack( "返回给Toast的alert");
}
});
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/** * 给Html发消息,js接收并返回数据 */
bridgeWebView.callHandler("functionInJs", "调用js的方法", new CallBackFunction() {
@Override
public void onCallBack(String data) {
showToast("===" + data);
}
});
}
});
}
public void showToast (String msg){
Toast.makeText(this,msg, Toast.LENGTH_SHORT).show();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// 处理返回键,在webview界面,按下返回键,不退出程序
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (bridgeWebView != null && bridgeWebView.canGoBack()) {
bridgeWebView.goBack();
return true;
}else {
System.exit(0);
}
}
return super.onKeyDown(keyCode, event);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
自定义MyWebViewClient.java :
package com.win.jsbridgetest;
import android.graphics.Bitmap;
import android.webkit.WebView;
import com.github.lzyzsd.jsbridge.BridgeWebView;
import com.github.lzyzsd.jsbridge.BridgeWebViewClient;
/** * Created by hzk on 2017/2/27. */
public class MyWebViewClient extends BridgeWebViewClient {
public MyWebViewClient(BridgeWebView context) {
super(context);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
界面布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".JsTestActivity">
<com.github.lzyzsd.jsbridge.BridgeWebView android:id="@+id/JsBridgeWebView" android:layout_width="match_parent" android:layout_height="400dp">
</com.github.lzyzsd.jsbridge.BridgeWebView>
<Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="給Html发送消息并返回消息" android:id="@+id/button3" />
</LinearLayout>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
前端页面的代码:
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<title>js调用java</title>
</head>
<body>
<p>
<input type="text" id="hint" value="调用安卓的Toast方法"/>
</p>
<p>
<input type="button" id="enter" value="调用安卓的方法" onclick="testClick();"/>
</p>
<script> // 发送消息给Android function testClick() {
var data = document.getElementById("hint").value; // 调用java中的方法 submitFromWeb是方法名 window.WebViewJavascriptBridge.callHandler( 'submitFromWeb' , {
'param': data} , function(responseData) {
alert(responseData) } ); } // 注册事件监听 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': 'Hello jarry!' }; responseCallback(data); }); // 接收安卓发来的消息 并返回给安卓通知 bridge.registerHandler("functionInJs", function(data, responseCallback) {
alert(data); var responseData = "我接受到了安卓的调用"; responseCallback(responseData); }); }) </script>
</body>
</html>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/production/markdown_views-ea0013b516.css">
</div>
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/25081.html