/**
* jsBridge原理
* https://www.jianshu.com/p/2ec3f06d6087
*/
public class MainActivity extends AppCompatActivity {
@BindView(R.id.webView)
WebView webView;
@BindView(R.id.txt_msg)
TextView txtMsg;
@BindView(R.id.btn_show)
Button btnShow;
@BindView(R.id.btn_webview)
Button btnWebview;
@BindView(R.id.btn_net)
Button btnNet;
@BindView(R.id.btns)
LinearLayout btns;
@BindView(R.id.btn_test)
Button btnTest;
@BindView(R.id.img)
ImageView img;
@BindView(R.id.btn_execute)
Button btnExecute;
@BindView(R.id.jsBridge)
BridgeWebView jsBridge;
@BindView(R.id.btn_bridge)
Button btnBridge;
private Context context;
//如果是本地的html文件用webView打开
private String local_url = "file:////android_asset/user_info.html";
//layabox3d 测试地址
//private String local_url = "http://layaair.ldc.layabox.com/demo/h5/demo.html?category=3d&group=particle&name=Particle_EternalLight&lib=core,webgl,ani,d3";
//如果是网络地址用默认浏览器打开
private String net_url = "http://www.baidu.com";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
context = this;
showUrl(local_url);
//初始化Bridge
initBridge();
}
private void initBridge(){
jsBridge.setDefaultHandler(new DefaultHandler());
jsBridge.setWebChromeClient(new WebChromeClient());
jsBridge.loadUrl(local_url);
//注册给js调用的方法
jsBridge.registerHandler("submitFromWeb", new BridgeHandler() {
//function js回调
@Override
public void handler(String data, CallBackFunction function) {
Toast.makeText(context,"js返回:"+data,Toast.LENGTH_SHORT).show();
function.onCallBack("android接收到数据了回传给js");
}
});
}
/**
* 根据参数显示对应的内容
*/
private void showUrl(String url) {
if (url.indexOf("http") != -1 || url.indexOf("https") != -1) {
loadNetHtml();
} else {
initLoadHtml();
}
}
/**
* https://www.jianshu.com/p/0d7d429bd216 WebSettings设置的属性介绍
*/
private void initLoadHtml() {
//local_url = "http://layaair.ldc.layabox.com/demo/h5/demo.html?category=3d&group=particle&name=Particle_EternalLight&lib=core,webgl,ani,d3";
webView.loadUrl(local_url);
//设置编码
WebSettings webSettings = webView.getSettings();
webSettings.setDefaultTextEncodingName("utf-8");
//支持js
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
MyJavaScript myObj = new MyJavaScript();
//设置本地调用对象及其接口
webView.addJavascriptInterface(myObj, "myObj");
//判断webview中是否能回退页面
//webView.goBack();
//webView.canGoBack();
webView.setWebChromeClient(new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
//页面加载完成
if(newProgress == 100){
//callJavascriptFun();
callJsFun();
}
}
});
}
/**
* 通过evaluateJavascript的方式访问接口
*/
private void callJavascriptFun(){
webView.evaluateJavascript("javascript:callByAndroid('from android data!')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Toast.makeText(context, value, Toast.LENGTH_SHORT).show();
}
});
}
/**
* 用默认的浏览器打开对应的网页
* 除了默认的浏览器可以打开,还可以用指定的浏览器打开
* uc浏览器":"com.uc.browser", "com.uc.browser.ActivityUpdate“
* opera:"com.opera.mini.android", "com.opera.mini.android.Browser"
* qq浏览器:"com.tencent.mtt", "com.tencent.mtt.MainActivity"
*/
private void loadNetHtml() {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
Uri content_url = Uri.parse(net_url);
intent.setData(content_url);
intent.setClassName("com.tencent.mtt", "com.tencent.mtt.MainActivity");
startActivity(intent);
}
@OnClick({R.id.btn_show, R.id.btn_test, R.id.btn_net, R.id.btn_webview,R.id.btn_execute,R.id.btn_bridge})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.btn_show:
webView.loadUrl("javascript:showMsg('from Android')");
break;
case R.id.btn_net:
showUrl(net_url);
break;
case R.id.btn_webview:
showUrl(local_url);
break;
case R.id.btn_test:
PackageManager pg = MyApp.app.getPackageManager();
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("xl://login:8888/loginPage?username=张三"));
List<ResolveInfo> activities = pg.queryIntentActivities(intent, 0);
boolean isValid = !activities.isEmpty();
if (isValid) {
startActivity(intent);
}
break;
case R.id.btn_execute:
callJsFun();
break;
case R.id.btn_bridge:
callJsBridge();
break;
}
}
/**
* android 4.4以后才有,调用不会刷新整个页面
* 必须在html加载完成以后才能调用
* execute javascript function
*/
private void callJsFun(){
webView.evaluateJavascript("javascript:fromAndroidCall('hello android')", new ValueCallback<String>() {
//如果没有设置返回值value = null
@Override
public void onReceiveValue(String value) {
Toast.makeText(context, value, Toast.LENGTH_SHORT).show();
}
});
}
/**
* 访问js的Bridge
*/
private void callJsBridge(){
jsBridge.callHandler("callJs", "Android调用js", new CallBackFunction() {
@Override
public void onCallBack(String data) {
Toast.makeText(context,data,Toast.LENGTH_SHORT).show();
}
});
}
/**
* android与js接口调用的通信类
*/
class MyJavaScript {
/**
*
* Android4.2以下的addJavascriptInterface存在安全漏洞
* Android4.2之后用@JavascriptInterface代替了
* 给到Javascript调用
*
* @param msg js传过来的参数
*/
@JavascriptInterface
public void showTipsFromJs(String msg) {
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
if (!TextUtils.isEmpty(msg)) {
txtMsg.setText(msg);
}
}
/**
* 显示js传送过来的图片数据
*
* @param imgData
*/
@JavascriptInterface
public void showImgFromJs(String imgData) {
imgData = imgData.replace("data:image/png;base64,","");
final Bitmap bmp = stringToBmp(imgData);
if(bmp != null) {
img.post(new Runnable() {
@Override
public void run() {
img.setImageBitmap(bmp);
}
});
}
}
}
/**
* base64 转 bitmap
*
* @param content
* @return
*/
private Bitmap stringToBmp(String content) {
Bitmap bitmap = null;
try {
byte[] bytes;
bytes = Base64.decode(content, Base64.DEFAULT);
bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
} catch (Exception e) {
e.printStackTrace();
}
return bitmap;
}
}
js
<html>
<head>
<meta charset="UTF-8">
</head>
<body onload="pageOnload()">
<div>输入内容提供给android显示:<input type="input" name="user_name" id="txt_input"></div>
<div>显示来至android内容:<input type="text" name="show_msg" id="txt_showmsg"></div>
<div name="div_name">
<input type="button" name="submit" id="submit" onclick="submitAndroid()" value="提交到android">
</div>
<div name="div_name">
<a href="xl://login:8888/loginPage?username=李四">打开android登录页面</a>
</div>
<div style="background-color:#ff0000">
<img id="img_icon" style="width:100px;height:100px;background-color:#cccccc">
</div>
<div>
<input type="button" value="img base64传入到android" onclick="sendImgToAndroid()">
</div>
<div>
<input type="button" value="jsBridge 调用" onclick="callBridge()">
</div>
<!--脚本-->
<script type="text/javascript">
//同步回调
function fromAndroidCall(str){
alert(str);
}
//调用bridge
function callBridge(){
//参数1调用java中注册的方法,submitFromWeb是方法名
//参数2返回给Android端的数据,可以String
//参数3js接收android端回传的数据
window.WebViewJavascriptBridge.callHandler(
"submitFromWeb",
{"param":"JS接收数据"},
function(responseData){
alert(responseData);
}
);
}
//创建被android调用的方法
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 Respond":"Bridge"
};
alert("alert bridge");
responseCallback(data);
});
//注册给android调用的方法
bridge.registerHandler("callJs",function(data,responseCallback){
alert(data);
responseCallback("callJs回调给anroid");
});
});
//传递数据到android
function submitAndroid(){
var str = document.getElementById("txt_input").value;
//把window看作webview myObj用着js调用android的内部类
window.myObj.showTipsFromJs(str);
}
//给Android调用的接口
function showMsg(msg){
var txt_msg = document.getElementById("txt_showmsg");
txt_msg.value = msg;
}
//android调用的方法
function callByAndroid(msg){
var txt_msg = document.getElementById("txt_showmsg");
txt_msg.value = msg;
return "调用完成";
}
//把img转成base64传入android
function getBase64Img(img){
var cas = document.createElement("canvas");
cas.width = img.width;
cas.height = img.height;
var ctx = cas.getContext("2d");
ctx.drawImage(img,0,0,img.width,img.height);
//格式可以是 image/png image/jpeg
var img_data = cas.toDataURL("image/jpg");
window.myObj.showImgFromJs(img_data);
}
function sendImgToAndroid(){
var img = document.getElementById("img_icon");
getBase64Img(img);
}
function pageOnload(){
var divs = document.getElementsByName("div_name");
var img = document.getElementById("img_icon");
img.setAttribute('crossOrigin', 'anonymous');
img.src = "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3660681135,2179565665&fm=26&gp=0.jpg";
}
</script>
</body>
</html>
网友评论