版权声明:本文为HaiyuKing原创文章,转载请注明出处!

前言

使用的是第三方库lzyzsd/JsBridge,但是不同的是,将自己封装的MyBridgeWebView通过继承BridgeWebView来使用,而不是使用第三方库的com.github.lzyzsd.jsbridge.BridgeWebView

效果图

代码分析

一、自封装的webview如何继承BridgeWebView

1、自定义的MyBridgeWebView继承BridgeWebView

2、自定义的MyBridgeWebViewClient继承BridgeWebViewClient,并重写shouldOverrideUrlLoading方法

    /**
* 重写此方法表明点击网页内的链接由自己处理,而不是新开Android的系统browser中响应该链接。
*/
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url) {
Log.e(TAG,"{shouldOverrideUrlLoading}url="+url);
if(url.startsWith("tel:")) {
Intent intent = new Intent("android.intent.action.VIEW", Uri.parse(url));
context.startActivity(intent);
return true;
}else{
/*//view.loadUrl(url);//根据传入的参数再去加载新的网页
return false;//表示当前的webview可以处理打开新网页的请求,不用借助系统浏览器,【false 显示frameset, true 不显示Frameset】*/
return super.shouldOverrideUrlLoading(webView,url);//为了实现Bridge
}
}

二、本demo中Mainactivity.java、demo.html和JsBridge相关的最初始的代码【在此基础上根据实际情况添加其他代码】

1、demo.html文件

<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>
js和java互调
</title>
</head> <body> </body>
<!--用于解析json数据-->
<script type="text/javascript" src="json2.js"></script>
<script> /*=====================================JSBridge==================================================*/
//注册事件监听
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': 'js初始化响应!'
};
responseCallback(data); }); //【Java调用的js方法】--用于js发送初始化后的消息给Java【由Java控制执行,在webviewClient的onPageFinished中执行】
//java执行onPageFinished后,调用这个方法;然后js发送消息给java;java接收并处理后回调js的initData()方法
bridge.registerHandler("sendMegToJavaFunctionInJs", function(data, responseCallback) {
//发送消息(onPageFinished 可以理解为handle的message.what),告诉java,HTML页面已经加载完成,可以开始请求接口获取数据了
window.WebViewJavascriptBridge.send(
"onPageFinished"
, function(responseData) {
//responseData 可以理解为回调返回的字符串数据
initData(responseData);
}
);
responseCallback("js已发送消息给java");//java调用js方法,都要返回data数据,不过这里因为是初始化的操作,所以返回空值即可。
}); }) /*=====webviewClient的onPageFinished执行后,js发送消息给java,然后java处理后回调js的方法======*/
function initData(data){
console.log("{initData}data="+data);
//根据实际情况,进行赋值;或者不做任何处理 }
</script> </html>

2、MainActivity.java文件

package com.why.project.mybridgewebviewdemo;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast; import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView;
import com.why.project.mybridgewebviewdemo.customwebview.utils.WebviewGlobals; public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName(); /**jsBridgeWebview*/
private MyBridgeWebView myWebView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initViews();
initDatas();
initEvents();
} private void initViews() {
myWebView = findViewById(R.id.web_view);
} private void initDatas() {
myWebView.setDefaultHandler(new CustomBridgeHandler());//jsBridge
//加载网址
myWebView.loadLocalUrl("demo.html");
initJsBridge(); //实现webview只可滑动不可点击【项目中需要用到的时候再解开注释】
//http://blog.csdn.net/mjjmjc/article/details/47105001
//http://blog.csdn.net/qq_32452623/article/details/52304628
/*myWebView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return true;
}
});*/
} /*=================================jsBridge=================================*/
/**
* 自定义BridgeHandler【用于接收html发送给Java的消息(通过data的值区分是哪个消息;function用于回调给js)】*/
class CustomBridgeHandler implements BridgeHandler {
@Override
public void handler(String data, CallBackFunction function) {
Log.i(TAG, "接收html发送给Java的消息(通过data的值区分是哪个消息):" + data);
if(data.equals("onPageFinished")){//onPageFinished 跟html中的保持一致
// TODO 请求接口获取数据
if(function != null){
function.onCallBack("这个是onPageFinished方法执行后js发送给java消息后,java回调给js的初始值");
}
}else{ }
}
} //jsBridge 初始化一些事件监听
private void initJsBridge(){ } private void initEvents() { } }

三、新增js发送消息给native的功能

1、在HTML界面中增加类似下面的代码【绿色标记的是用来显示java返回给js的数据】

<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>
js和java互调
</title>
</head> <body>
<p>
<input type="text" id="show" style="width:100%;"/>
</p>
<p>
<input type="button" id="enter" value="js发消息给Native" onclick="sendMegToJava();"
/>
</p> </body>
<!--用于解析json数据-->
<script type="text/javascript" src="json2.js"></script>
<script> //发消息给Native 按钮的点击事件
//发送的消息是到BridgeHandler子类的handler方法中进行匹配
function sendMegToJava() {
//尽量使用json数据
var message = "getNewData";//消息数据(可以直接是一个字符串,作为消息类型(比如getNewData);也可以是一个json字符串,根据key值进行判断类型)
window.WebViewJavascriptBridge.send(
message
, function(responseData) {
document.getElementById("show").value = responseData;
}
);
}/*=====================================JSBridge==================================================*/
//注册事件监听
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': 'js初始化响应!'
};
responseCallback(data); });
}) /*=====webviewClient的onPageFinished执行后,js发送消息给java,然后java处理后回调js的方法======*/
function initData(data){
console.log("{initData}data="+data);
//根据实际情况,进行赋值;或者不做任何处理
}
</script> </html>

2、在java类中添加以下代码

package com.why.project.mybridgewebviewdemo;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast; import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView;
import com.why.project.mybridgewebviewdemo.customwebview.utils.WebviewGlobals; public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName(); /**jsBridgeWebview*/
private MyBridgeWebView myWebView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initViews();
initDatas();
initEvents();
} private void initViews() {
myWebView = findViewById(R.id.web_view);
} private void initDatas() {
myWebView.setDefaultHandler(new CustomBridgeHandler());//jsBridge
//加载网址
myWebView.loadLocalUrl("demo.html");
initJsBridge(); //实现webview只可滑动不可点击【项目中需要用到的时候再解开注释】
//http://blog.csdn.net/mjjmjc/article/details/47105001
//http://blog.csdn.net/qq_32452623/article/details/52304628
/*myWebView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return true;
}
});*/
} /*=================================jsBridge=================================*/
/**
* 自定义BridgeHandler【用于接收html发送给Java的消息(通过data的值区分是哪个消息;function用于回调给js)】*/
class CustomBridgeHandler implements BridgeHandler {
@Override
public void handler(String data, CallBackFunction function) {
Log.i(TAG, "接收html发送给Java的消息(通过data的值区分是哪个消息):" + data);
if(data.equals("onPageFinished")){//onPageFinished 跟html中的保持一致
// TODO 请求接口获取数据
if(function != null){
function.onCallBack("这个是onPageFinished方法执行后js发送给java消息后,java回调给js的初始值");
}
}else{
if(data.equals("getNewData")){
// TODO 请求接口获取数据
if(function != null){
function.onCallBack("这个是js发送给java消息后返回的数据");
}
}
}
}
} //jsBridge 初始化一些事件监听
private void initJsBridge(){
} }

四、新增js调用native方法的功能

1、在HTML界面中增加类似下面的代码【绿色标记的是用来显示java返回给js的数据】

<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>
js和java互调
</title>
</head> <body>
<p>
<input type="text" id="show" style="width:100%;"/>
</p>
<p>
<input type="button" id="enter1" value="js调用Native的方法" onclick="callJavaMethod();"
/>
</p>
</body>
<!--用于解析json数据-->
<script type="text/javascript" src="json2.js"></script>
<script> //调用Native方法 按钮的点击事件
//调用的java方法需要在activity界面中进行声明,参考initJsBridge()方法中的声明方法
function callJavaMethod() {
//尽量使用json数据
var dataObj = new Object();
dataObj.id = ;
dataObj.title = "这是一个标题"
dataObj.isNew = true;
var dataObjStr = JSON.stringify(dataObj); //functionInJava : 在Activity界面的initJsBridge()中声明的方法
window.WebViewJavascriptBridge.callHandler(
'functionInJava'
, {'param': dataObjStr}
, function(responseData) {
document.getElementById("show").value = responseData;
}
);
}/*=====================================JSBridge==================================================*/
//注册事件监听
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': 'js初始化响应!'
};
responseCallback(data); }); //【Java调用的js方法】--用于js发送初始化后的消息给Java【由Java控制执行,在webviewClient的onPageFinished中执行】
//java执行onPageFinished后,调用这个方法;然后js发送消息给java;java接收并处理后回调js的initData()方法
bridge.registerHandler("sendMegToJavaFunctionInJs", function(data, responseCallback) {
//发送消息(onPageFinished 可以理解为handle的message.what),告诉java,HTML页面已经加载完成,可以开始请求接口获取数据了
window.WebViewJavascriptBridge.send(
"onPageFinished"
, function(responseData) {
//responseData 可以理解为回调返回的字符串数据
initData(responseData);
}
);
responseCallback("js已发送消息给java");//java调用js方法,都要返回data数据,不过这里因为是初始化的操作,所以返回空值即可。
});
}) /*=====webviewClient的onPageFinished执行后,js发送消息给java,然后java处理后回调js的方法======*/
function initData(data){
console.log("{initData}data="+data);
//根据实际情况,进行赋值;或者不做任何处理
}
</script> </html>

2、在java类中添加以下代码

package com.why.project.mybridgewebviewdemo;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast; import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView;
import com.why.project.mybridgewebviewdemo.customwebview.utils.WebviewGlobals; public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName(); /**jsBridgeWebview*/
private MyBridgeWebView myWebView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initViews();
initDatas();
initEvents();
} private void initViews() {
myWebView = findViewById(R.id.web_view);
} private void initDatas() {
myWebView.setDefaultHandler(new CustomBridgeHandler());//jsBridge
//加载网址
myWebView.loadLocalUrl("demo.html");
initJsBridge(); //实现webview只可滑动不可点击【项目中需要用到的时候再解开注释】
//http://blog.csdn.net/mjjmjc/article/details/47105001
//http://blog.csdn.net/qq_32452623/article/details/52304628
/*myWebView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return true;
}
});*/
} /*=================================jsBridge=================================*/
/**
* 自定义BridgeHandler【用于接收html发送给Java的消息(通过data的值区分是哪个消息;function用于回调给js)】*/
class CustomBridgeHandler implements BridgeHandler {
@Override
public void handler(String data, CallBackFunction function) {
Log.i(TAG, "接收html发送给Java的消息(通过data的值区分是哪个消息):" + data);
if(data.equals("onPageFinished")){//onPageFinished 跟html中的保持一致
// TODO 请求接口获取数据
if(function != null){
function.onCallBack("这个是onPageFinished方法执行后js发送给java消息后,java回调给js的初始值");
}
}else{
}
}
} //jsBridge 初始化一些事件监听
private void initJsBridge(){
//【js调用Java的方法】必须和js中的调用函数名相同,注册具体执行函数,类似java实现类。
myWebView.registerHandler("functionInJava", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
Log.i(TAG, "接收html发送给Java的数据:" + data); String callbackData = "这个是js调用java方法后返回的数据";
function.onCallBack(callbackData);
}
});
} private void initEvents() {
} }

五、新增native调用js方法的功能

1、在HTML界面中增加类似下面的代码【绿色标记的是用来显示java返回给js的数据】

<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>
js和java互调
</title>
</head> <body>
<p>
<input type="text" id="show" style="width:100%;"/>
</p> </body>
<!--用于解析json数据-->
<script type="text/javascript" src="json2.js"></script>
<script> //java调用js方法实际执行的方法
function handleJavaData(dataObj){
document.getElementById("show").value = "用户名=" + dataObj.username + ";密码=" + dataObj.password;
return "登录成功呢";
} /*=====================================JSBridge==================================================*/
//注册事件监听
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': 'js初始化响应!'
};
responseCallback(data); }); //【Java调用的js方法】--用于js发送初始化后的消息给Java【由Java控制执行,在webviewClient的onPageFinished中执行】
//java执行onPageFinished后,调用这个方法;然后js发送消息给java;java接收并处理后回调js的initData()方法
bridge.registerHandler("sendMegToJavaFunctionInJs", function(data, responseCallback) {
//发送消息(onPageFinished 可以理解为handle的message.what),告诉java,HTML页面已经加载完成,可以开始请求接口获取数据了
window.WebViewJavascriptBridge.send(
"onPageFinished"
, function(responseData) {
//responseData 可以理解为回调返回的字符串数据
initData(responseData);
}
);
responseCallback("js已发送消息给java");//java调用js方法,都要返回data数据,不过这里因为是初始化的操作,所以返回空值即可。
}); /*============================自定义java调用的js方法声明【根据实际情况声明方法】===========================================*/
//【Java调用的js方法】
bridge.registerHandler("functionInJs", function(data, responseCallback) {
//JSON.parse(jsonstr); //方法一:可以将json字符串转换成json对象
//JSON.stringify(jsonobj); //方法二:可以将json对象转换成json对符串 var dataObj = JSON.parse(data);//将发送过来的数据转为json对象 //一般都有一个配套的js方法,用于处理接收到的数据
var responseData = handleJavaData(dataObj); responseCallback(responseData);
});
}) /*=====webviewClient的onPageFinished执行后,js发送消息给java,然后java处理后回调js的方法======*/
function initData(data){
console.log("{initData}data="+data);
//根据实际情况,进行赋值;或者不做任何处理
}
</script> </html>

2、在java类中添加以下代码

package com.why.project.mybridgewebviewdemo;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast; import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView;
import com.why.project.mybridgewebviewdemo.customwebview.utils.WebviewGlobals; public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName(); /**jsBridgeWebview*/
private MyBridgeWebView myWebView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initViews();
initDatas();
initEvents();
} private void initViews() {
myWebView = findViewById(R.id.web_view);
} private void initDatas() {
myWebView.setDefaultHandler(new CustomBridgeHandler());//jsBridge
//加载网址
myWebView.loadLocalUrl("demo.html");
initJsBridge(); //实现webview只可滑动不可点击【项目中需要用到的时候再解开注释】
//http://blog.csdn.net/mjjmjc/article/details/47105001
//http://blog.csdn.net/qq_32452623/article/details/52304628
/*myWebView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return true;
}
});*/
} /*=================================jsBridge=================================*/
/**
* 自定义BridgeHandler【用于接收html发送给Java的消息(通过data的值区分是哪个消息;function用于回调给js)】*/
class CustomBridgeHandler implements BridgeHandler {
@Override
public void handler(String data, CallBackFunction function) {
Log.i(TAG, "接收html发送给Java的消息(通过data的值区分是哪个消息):" + data);
if(data.equals("onPageFinished")){//onPageFinished 跟html中的保持一致
// TODO 请求接口获取数据
if(function != null){
function.onCallBack("这个是onPageFinished方法执行后js发送给java消息后,java回调给js的初始值");
}
}else{
}
}
} //jsBridge 初始化一些事件监听
private void initJsBridge(){
} private void initEvents() {
findViewById(R.id.btn_calljsfunction).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Java调用js的方法
//发送给js的参数,使用Json格式
String params = "{\"username\":\"why\",\"password\":\"123456\"}";
myWebView.callHandler("functionInJs",params, new CallBackFunction() {
@Override
public void onCallBack(String data) {
// TODO Auto-generated method stub
//处理html返回给Java的数据
Toast.makeText(MainActivity.this,data,Toast.LENGTH_SHORT).show();
}
});
}
});
} }

六、选择文件的功能

1、在HTML界面中增加类似下面的代码

<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>
js和java互调
</title>
</head> <body>
<p>
<input type="file" value="打开文件" />
</p>
</body>
<script>
</script> </html>

2、在java类中添加以下代码

package com.why.project.mybridgewebviewdemo;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast; import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView;
import com.why.project.mybridgewebviewdemo.customwebview.utils.WebviewGlobals; public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName(); /**jsBridgeWebview*/
private MyBridgeWebView myWebView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initViews();
initDatas();
initEvents();
} private void initViews() {
myWebView = findViewById(R.id.web_view);
} private void initDatas() {
myWebView.setDefaultHandler(new CustomBridgeHandler());//jsBridge
//加载网址
myWebView.loadLocalUrl("demo.html");
initJsBridge(); //实现webview只可滑动不可点击【项目中需要用到的时候再解开注释】
//http://blog.csdn.net/mjjmjc/article/details/47105001
//http://blog.csdn.net/qq_32452623/article/details/52304628
/*myWebView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return true;
}
});*/
} /*=================================jsBridge=================================*/
/**
* 自定义BridgeHandler【用于接收html发送给Java的消息(通过data的值区分是哪个消息;function用于回调给js)】*/
class CustomBridgeHandler implements BridgeHandler {
@Override
public void handler(String data, CallBackFunction function) {
Log.i(TAG, "接收html发送给Java的消息(通过data的值区分是哪个消息):" + data);
if(data.equals("onPageFinished")){//onPageFinished 跟html中的保持一致
// TODO 请求接口获取数据
if(function != null){
function.onCallBack("这个是onPageFinished方法执行后js发送给java消息后,java回调给js的初始值");
}
}else{
}
}
} //jsBridge 初始化一些事件监听
private void initJsBridge(){
} private void initEvents() {
} /*=========================================实现webview调用选择文件的功能==============================================*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.w(TAG, "{onActivityResult}resultCode="+resultCode);
Log.w(TAG, "{onActivityResult}requestCode="+requestCode);
Log.w(TAG, "{onActivityResult}data="+data);
if (resultCode == Activity.RESULT_OK) {
//webview界面调用打开本地文件管理器选择文件的回调
if (requestCode == WebviewGlobals.CHOOSE_FILE_REQUEST_CODE ) {
Uri result = data == null ? null : data.getData();
Log.w(TAG,"{onActivityResult}文件路径地址:" + result.toString()); //如果mUploadMessage或者mUploadCallbackAboveL不为空,代表是触发input[type]类型的标签
if (null != myWebView.getMyBridgeWebChromeClient().getmUploadMessage() || null != myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL()) {
if (myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL() != null) {
onActivityResultAboveL(requestCode, data);//5.0++
} else if (myWebView.getMyBridgeWebChromeClient().getmUploadMessage() != null) {
myWebView.getMyBridgeWebChromeClient().getmUploadMessage().onReceiveValue(result);//将文件路径返回去,填充到input中
myWebView.getMyBridgeWebChromeClient().setmUploadMessage(null);
}
}else{
//此处代码是处理通过js方法触发的情况
Log.w(TAG,"{onActivityResult}文件路径地址(js):" + result.toString());
}
}
}else if(resultCode == RESULT_CANCELED){//resultCode == RESULT_CANCELED 解决不选择文件,直接返回后无法再次点击的问题
if (myWebView.getMyBridgeWebChromeClient().getmUploadMessage() != null) {
myWebView.getMyBridgeWebChromeClient().getmUploadMessage().onReceiveValue(null);
myWebView.getMyBridgeWebChromeClient().setmUploadMessage(null);
}
if (myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL() != null) {
myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL().onReceiveValue(null);
myWebView.getMyBridgeWebChromeClient().setmUploadCallbackAboveL(null);
}
}
} //5.0以上版本,由于api不一样,要单独处理
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, Intent data) { if (myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL() == null) {
return;
}
Uri result = null;
if (requestCode == WebviewGlobals.CHOOSE_FILE_REQUEST_CODE) {//打开本地文件管理器选择图片
result = data == null ? null : data.getData();
}
Log.w(TAG,"{onActivityResultAboveL}文件路径地址:"+result.toString());
myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL().onReceiveValue(new Uri[]{result});//将文件路径返回去,填充到input中
myWebView.getMyBridgeWebChromeClient().setmUploadCallbackAboveL(null);
return;
} }

使用步骤

一、项目组织结构图

注意事项:

1、  导入类文件后需要change包名以及重新import R文件路径

2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

二、导入步骤

1、在app的build.gradle文件中引用JsBridge第三方库

apply plugin: 'com.android.application'

android {
compileSdkVersion 27
defaultConfig {
applicationId "com.why.project.mybridgewebviewdemo"
minSdkVersion 16
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
//jsbridge
repositories{
//jsBridge
maven { url "https://jitpack.io" }
} dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' //jsBridge
compile 'com.github.lzyzsd:jsbridge:1.0.4'
}

2、将assets文件夹复制到项目中

demo.html【用于演示选择文件、js发消息给native、js调用native的方法、native调用js方法的功能】

<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>
js和java互调
</title>
</head> <body>
<p>
<input type="text" id="show" style="width:100%;"/>
</p>
<p>
<input type="button" id="enter" value="js发消息给Native" onclick="sendMegToJava();"
/>
</p>
<p>
<input type="button" id="enter1" value="js调用Native的方法" onclick="callJavaMethod();"
/>
</p>
<p>
<input type="file" value="打开文件" />
</p>
</body>
<!--用于解析json数据-->
<script type="text/javascript" src="json2.js"></script>
<script> //发消息给Native 按钮的点击事件
//发送的消息是到BridgeHandler子类的handler方法中进行匹配
function sendMegToJava() {
//尽量使用json数据
var message = "getNewData";//消息数据(可以直接是一个字符串,作为消息类型(比如getNewData);也可以是一个json字符串,根据key值进行判断类型)
window.WebViewJavascriptBridge.send(
message
, function(responseData) {
document.getElementById("show").value = responseData;
}
);
} //调用Native方法 按钮的点击事件
//调用的java方法需要在activity界面中进行声明,参考initJsBridge()方法中的声明方法
function callJavaMethod() {
//尽量使用json数据
var dataObj = new Object();
dataObj.id = 153273;
dataObj.title = "这是一个标题"
dataObj.isNew = true;
var dataObjStr = JSON.stringify(dataObj); //functionInJava : 在Activity界面的initJsBridge()中声明的方法
window.WebViewJavascriptBridge.callHandler(
'functionInJava'
, {'param': dataObjStr}
, function(responseData) {
document.getElementById("show").value = responseData;
}
);
} //java调用js方法实际执行的方法
function handleJavaData(dataObj){
document.getElementById("show").value = "用户名=" + dataObj.username + ";密码=" + dataObj.password;
return "登录成功呢";
} /*=====================================JSBridge==================================================*/
//注册事件监听
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': 'js初始化响应!'
};
responseCallback(data); }); //【Java调用的js方法】--用于js发送初始化后的消息给Java【由Java控制执行,在webviewClient的onPageFinished中执行】
//java执行onPageFinished后,调用这个方法;然后js发送消息给java;java接收并处理后回调js的initData()方法
bridge.registerHandler("sendMegToJavaFunctionInJs", function(data, responseCallback) {
//发送消息(onPageFinished 可以理解为handle的message.what),告诉java,HTML页面已经加载完成,可以开始请求接口获取数据了
window.WebViewJavascriptBridge.send(
"onPageFinished"
, function(responseData) {
//responseData 可以理解为回调返回的字符串数据
initData(responseData);
}
);
responseCallback("js已发送消息给java");//java调用js方法,都要返回data数据,不过这里因为是初始化的操作,所以返回空值即可。
}); /*============================自定义java调用的js方法声明【根据实际情况声明方法】===========================================*/
//【Java调用的js方法】
bridge.registerHandler("functionInJs", function(data, responseCallback) {
//JSON.parse(jsonstr); //方法一:可以将json字符串转换成json对象
//JSON.stringify(jsonobj); //方法二:可以将json对象转换成json对符串 var dataObj = JSON.parse(data);//将发送过来的数据转为json对象 //一般都有一个配套的js方法,用于处理接收到的数据
var responseData = handleJavaData(dataObj); responseCallback(responseData);
});
}) /*=====webviewClient的onPageFinished执行后,js发送消息给java,然后java处理后回调js的方法======*/
function initData(data){
console.log("{initData}data="+data);
//根据实际情况,进行赋值;或者不做任何处理
document.getElementById("show").value = data;
}
</script> </html>

demo.html

3、将customwebview包复制到项目中

4、将mybridgewebview_progress_dialog_img_drawable.xml复制到项目中

<?xml version="1.0" encoding="utf-8"?>
<!-- WebView使用的进度加载对话框进度圆圈 -->
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/mybridgewebview_progress_dialog_img"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0.0"
android:toDegrees="360.0"
android:repeatMode="restart"
/>

mybridgewebview_progress_dialog_img_drawable.xml

5、将mybridgewebview_progress_dialog_img.png图片复制到项目中

6、将mybridgewebview_dialog_webviewprogress.xml复制到项目中

<?xml version="1.0" encoding="utf-8"?>
<!-- WebView使用的进度加载对话框布局文件 -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialog_view"
android:layout_width="match_parent"
android:layout_height="match_parent"> <!-- 自定义圆形进度条 -->
<!-- android:indeterminateDrawable自定义动画图标 -->
<ProgressBar
android:id="@+id/loadProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:indeterminateDrawable="@drawable/mybridgewebview_progress_dialog_img_drawable"
/> </RelativeLayout>

mybridgewebview_dialog_webviewprogress.xml

7、在styles.xml文件中添加以下代码

<resources>

    <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style> <!-- ==================MyBridgeWebView========网页加载时的进度对话框========================== -->
<style name="mybridgewebview_loading_style" parent="android:style/Theme.Dialog">
<!-- Dialog的windowFrame框为无 -->
<item name="android:windowFrame">@null</item>
<!-- 是否显示title -->
<item name="android:windowNoTitle">true</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 设置dialog的背景:#00000000透明色 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 半透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 背景变灰:整个屏幕变灰,配合setCanceledOnTouchOutside(false) -->
<item name="android:backgroundDimEnabled">false</item>
<!-- 对话框是否有遮盖 -->
<item name="android:windowContentOverlay">@null</item>
</style> </resources>

8、在AndroidManifest.xml中添加以下代码

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.why.project.mybridgewebviewdemo"> <!-- ======================(MyBridgeWebView)========================== -->
<!-- 允许程序打开网络套接字 -->
<uses-permission android:name="android.permission.INTERNET"/> <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application> </manifest>

三、使用方法

在布局文件activity_main.xml中声明【实际项目中实际新的完整路径】

<?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:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#bbbcbc"
android:orientation="vertical"> <!-- button 演示Java调用web -->
<Button
android:id="@+id/btn_calljsfunction"
android:layout_width="match_parent"
android:layout_height="48dp"
android:text="Native调用Js方法"
/> <com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/> </LinearLayout>

在Activity中使用如下

package com.why.project.mybridgewebviewdemo;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast; import com.github.lzyzsd.jsbridge.BridgeHandler;
import com.github.lzyzsd.jsbridge.CallBackFunction;
import com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView;
import com.why.project.mybridgewebviewdemo.customwebview.utils.WebviewGlobals; public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName(); /**jsBridgeWebview*/
private MyBridgeWebView myWebView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initViews();
initDatas();
initEvents();
} private void initViews() {
myWebView = findViewById(R.id.web_view);
} private void initDatas() {
myWebView.setDefaultHandler(new CustomBridgeHandler());//jsBridge
//加载网址
myWebView.loadLocalUrl("demo.html");
initJsBridge(); //实现webview只可滑动不可点击【项目中需要用到的时候再解开注释】
//http://blog.csdn.net/mjjmjc/article/details/47105001
//http://blog.csdn.net/qq_32452623/article/details/52304628
/*myWebView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return true;
}
});*/
} /*=================================jsBridge=================================*/
/**
* 自定义BridgeHandler【用于接收html发送给Java的消息(通过data的值区分是哪个消息;function用于回调给js)】*/
class CustomBridgeHandler implements BridgeHandler {
@Override
public void handler(String data, CallBackFunction function) {
Log.i(TAG, "接收html发送给Java的消息(通过data的值区分是哪个消息):" + data);
if(data.equals("onPageFinished")){//onPageFinished 跟html中的保持一致
// TODO 请求接口获取数据
if(function != null){
function.onCallBack("这个是onPageFinished方法执行后js发送给java消息后,java回调给js的初始值");
}
}else{
if(data.equals("getNewData")){
// TODO 请求接口获取数据
if(function != null){
function.onCallBack("这个是js发送给java消息后返回的数据");
}
}
}
}
} //jsBridge 初始化一些事件监听
private void initJsBridge(){
//【js调用Java的方法】必须和js中的调用函数名相同,注册具体执行函数,类似java实现类。
myWebView.registerHandler("functionInJava", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
Log.i(TAG, "接收html发送给Java的数据:" + data); String callbackData = "这个是js调用java方法后返回的数据";
function.onCallBack(callbackData);
}
});
} private void initEvents() {
findViewById(R.id.btn_calljsfunction).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Java调用js的方法
//发送给js的参数,使用Json格式
String params = "{\"username\":\"why\",\"password\":\"123456\"}";
myWebView.callHandler("functionInJs",params, new CallBackFunction() {
@Override
public void onCallBack(String data) {
// TODO Auto-generated method stub
//处理html返回给Java的数据
Toast.makeText(MainActivity.this,data,Toast.LENGTH_SHORT).show();
}
});
}
});
} /*=========================================实现webview调用选择文件的功能==============================================*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.w(TAG, "{onActivityResult}resultCode="+resultCode);
Log.w(TAG, "{onActivityResult}requestCode="+requestCode);
Log.w(TAG, "{onActivityResult}data="+data);
if (resultCode == Activity.RESULT_OK) {
//webview界面调用打开本地文件管理器选择文件的回调
if (requestCode == WebviewGlobals.CHOOSE_FILE_REQUEST_CODE ) {
Uri result = data == null ? null : data.getData();
Log.w(TAG,"{onActivityResult}文件路径地址:" + result.toString()); //如果mUploadMessage或者mUploadCallbackAboveL不为空,代表是触发input[type]类型的标签
if (null != myWebView.getMyBridgeWebChromeClient().getmUploadMessage() || null != myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL()) {
if (myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL() != null) {
onActivityResultAboveL(requestCode, data);//5.0++
} else if (myWebView.getMyBridgeWebChromeClient().getmUploadMessage() != null) {
myWebView.getMyBridgeWebChromeClient().getmUploadMessage().onReceiveValue(result);//将文件路径返回去,填充到input中
myWebView.getMyBridgeWebChromeClient().setmUploadMessage(null);
}
}else{
//此处代码是处理通过js方法触发的情况
Log.w(TAG,"{onActivityResult}文件路径地址(js):" + result.toString());
}
}
}else if(resultCode == RESULT_CANCELED){//resultCode == RESULT_CANCELED 解决不选择文件,直接返回后无法再次点击的问题
if (myWebView.getMyBridgeWebChromeClient().getmUploadMessage() != null) {
myWebView.getMyBridgeWebChromeClient().getmUploadMessage().onReceiveValue(null);
myWebView.getMyBridgeWebChromeClient().setmUploadMessage(null);
}
if (myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL() != null) {
myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL().onReceiveValue(null);
myWebView.getMyBridgeWebChromeClient().setmUploadCallbackAboveL(null);
}
}
} //5.0以上版本,由于api不一样,要单独处理
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, Intent data) { if (myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL() == null) {
return;
}
Uri result = null;
if (requestCode == WebviewGlobals.CHOOSE_FILE_REQUEST_CODE) {//打开本地文件管理器选择图片
result = data == null ? null : data.getData();
}
Log.w(TAG,"{onActivityResultAboveL}文件路径地址:"+result.toString());
myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL().onReceiveValue(new Uri[]{result});//将文件路径返回去,填充到input中
myWebView.getMyBridgeWebChromeClient().setmUploadCallbackAboveL(null);
return;
} }

混淆配置

注意:根据实际项目的路径修改下面表红色的文字

# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#} # Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile #====WebView + js====
-keepclassmembers class com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView {
public *;
}
-keepclassmembers class com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebChromeClient {
public *;
}
-keepclassmembers class com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebViewClient {
public *;
}
# keep 使用 webview 的类
-keepclassmembers class com.why.project.mybridgewebviewdemo.MainActivity {
public *;
}
-keepattributes *Annotation*
#解决:android sdk api >= 17 时需要加@JavascriptInterface”所出现的问题。
-keepattributes *JavascriptInterface*

参考资料

JsBridge

项目demo下载地址

https://github.com/haiyuKing/MyBridgeWebViewDemo

MyBridgeWebViewDemo【集成JsBridge开源库的的封装的webview】的更多相关文章

  1. 真香警告!JitPack 开源库集成平台

    前言: 请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 简介 官方介绍: JitPack 是一个用于 JVM 和 Android 项目的新颖的包存储库.它按需构建 Git 项目并为您提供即用 ...

  2. 2019最新Android常用开源库总结(附带github链接)

    前言 收集了一些比较常见的开源库,特此记录(已收录350+).另外,本文将持续更新,大家有关于Android 优秀的开源库,也可以在下面留言. 一 .基本控件 1.TextView HTextView ...

  3. Android 常用开源库总结(持续更新)

    前言 收集了一些比较常见的开源库,特此记录(已收录350+).另外,本文将持续更新,大家有关于Android 优秀的开源库,也可以在下面留言. 一 .基本控件 TextView HTextView 一 ...

  4. 各种Android UI开源框架 开源库

    各种Android UI开源框架 开源库 转 https://blog.csdn.net/zhangdi_gdk2016/article/details/84643668 自己总结的Android开源 ...

  5. 100个Github上Android开源库

    项目名称 项目简介 1. react-native 这个是 Facebook 在 React.js Conf 2015 大会上推出的基于 JavaScript 的开源框架 React Native, ...

  6. 介绍n款计算机视觉库/人脸识别开源库/软件

    计算机视觉库 OpenCV OpenCV是Intel®开源计算机视觉库.它由一系列 C 函数和少量 C++ 类构成,实现了图像处理和计算机视觉方面的很多通用算法. OpenCV 拥有包括 300 多个 ...

  7. iOS 项目中用到的一些开源库和第三方组件

    iOS 项目中用到的一些 iOS 开源库和第三方组件 分享一下我目前所在公司 iOS 项目中用到的一些 iOS 开源库和第三方组件, 感谢开源, 减少了我们的劳动力, 节约了我们大量的时间, 让我们有 ...

  8. iOS项目中常用的第三方开源库

    1.项目使用的第三方开源库 项目使用了CocoaPods(类似java中的maven)管理常用的第三方库,一些特殊的单独引用,下面介绍下比较好用的几个. (1)AFNetworking 目前比较推荐的 ...

  9. GitHub上排名前100的Android开源库介绍(来自github)

    本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍,至于排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果,然后过滤了 ...

随机推荐

  1. 运用BT在centos下搭建一个博客论坛

    在日常的工作和学习中,我们都很希望有自己的工作站,就是自己的服务器,自己给自己搭建一个博客或者是论坛,用于自己来写博客和搭建网站论坛.现在我们就用一个简单的方法来教大家如何30分钟内部署一个博客网站. ...

  2. go语言nsq源码解读九 tcp和http中channel、topic的增删

    通过前面多篇文章,nsqlookupd基本已经解读完毕了,不过在关于channel和topic的增删上还比较模糊,所以本篇将站在宏观的角度来总结一下,tcp.go和http.go两个文件中关于chan ...

  3. C++中使用引用作为函数参数的优点

    1.传递引用给函数与传递指针的效果是一样的.这时,被调函数的形参就成为原来主调函数中的实参变量或对象的一个别名来使用,所以在被调函数中对形参变量的操作就是对其相应的目标 对象(在主调函数中)的操作. ...

  4. 【二分贪心】Bzoj3969 [WF2013] Low Power

    Description 有n个机器,每个机器有2个芯片,每个芯片可以放k个电池. 每个芯片能量是k个电池的能量的最小值. 两个芯片的能量之差越小,这个机器就工作的越好. 现在有2nk个电池,已知它们的 ...

  5. Android 画文字图

    画图 private Bitmap getbitmap(String content) { Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.C ...

  6. 开源方案搭建可离线的精美矢量切片地图服务-2.PostGIS+GeoServer矢量切片

    项目成果展示(所有项目文件都在阿里云的共享云虚拟主机上,访问地图可以会有点慢,请多多包涵). 01:中国地图:http://test.sharegis.cn/mapbox/html/3china.ht ...

  7. (5)STM32使用HAL库实现串口通讯——实战操作

    功能需求: (1)对接收的字符串原样返回(每10个字符一次). (2)发送一个字符串完成后改变LED的状态. 1.创建工程 使用的是F407Discovery,4个LED对应PD12-PD14. (1 ...

  8. Postman----request的body中实现数据驱动

    使用场景: 一个接口多次执行,要求body中的某个参数在每次运行时都要填写不同的值,根据不同值的传入,返回不同的结果 参考示例:通过接口测试创建5条待办名称不一样的待办事项.名称格式不作要求 解决方法 ...

  9. subprocess实时获取结果和捕获错误

    需要调用命令行来执行某些命令,主要是用 subprocess 实时获取结果和捕获错误,发现subprocess的很多坑. subprocess 普通获取结果方式,其需要命令完全执行才能返回结果: im ...

  10. python接口自动化(十八)--重定向(Location)(详解)

    简介 在实际工作中,有些接口请求完以后会重定向到别的url,而你却需要重定向前的url.URL主要是针对虚拟空间而言,因为不是自己独立管理的服务器,所以无法正常进行常规的操作.但是自己又不希望通过主域 ...