MyBridgeWebViewDemo【集成JsBridge开源库的的封装的webview】
版权声明:本文为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*
参考资料
项目demo下载地址
https://github.com/haiyuKing/MyBridgeWebViewDemo
MyBridgeWebViewDemo【集成JsBridge开源库的的封装的webview】的更多相关文章
- 真香警告!JitPack 开源库集成平台
前言: 请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i 简介 官方介绍: JitPack 是一个用于 JVM 和 Android 项目的新颖的包存储库.它按需构建 Git 项目并为您提供即用 ...
- 2019最新Android常用开源库总结(附带github链接)
前言 收集了一些比较常见的开源库,特此记录(已收录350+).另外,本文将持续更新,大家有关于Android 优秀的开源库,也可以在下面留言. 一 .基本控件 1.TextView HTextView ...
- Android 常用开源库总结(持续更新)
前言 收集了一些比较常见的开源库,特此记录(已收录350+).另外,本文将持续更新,大家有关于Android 优秀的开源库,也可以在下面留言. 一 .基本控件 TextView HTextView 一 ...
- 各种Android UI开源框架 开源库
各种Android UI开源框架 开源库 转 https://blog.csdn.net/zhangdi_gdk2016/article/details/84643668 自己总结的Android开源 ...
- 100个Github上Android开源库
项目名称 项目简介 1. react-native 这个是 Facebook 在 React.js Conf 2015 大会上推出的基于 JavaScript 的开源框架 React Native, ...
- 介绍n款计算机视觉库/人脸识别开源库/软件
计算机视觉库 OpenCV OpenCV是Intel®开源计算机视觉库.它由一系列 C 函数和少量 C++ 类构成,实现了图像处理和计算机视觉方面的很多通用算法. OpenCV 拥有包括 300 多个 ...
- iOS 项目中用到的一些开源库和第三方组件
iOS 项目中用到的一些 iOS 开源库和第三方组件 分享一下我目前所在公司 iOS 项目中用到的一些 iOS 开源库和第三方组件, 感谢开源, 减少了我们的劳动力, 节约了我们大量的时间, 让我们有 ...
- iOS项目中常用的第三方开源库
1.项目使用的第三方开源库 项目使用了CocoaPods(类似java中的maven)管理常用的第三方库,一些特殊的单独引用,下面介绍下比较好用的几个. (1)AFNetworking 目前比较推荐的 ...
- GitHub上排名前100的Android开源库介绍(来自github)
本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍,至于排名完全是根据 GitHub 搜索 Java 语言选择 (Best Match) 得到的结果,然后过滤了 ...
随机推荐
- 提高测试脚本复用性降低DOM结构引起路径变化的影响
问题描述 在定位元素时直接复制的xpath. 但是因为下面这些原因导致之前引用的路径失效, 不得不频繁修改脚本重新定位元素, 大降低了脚本的复用性, 也增加了维护的成本: 1. UI修改 (比如增加了 ...
- MAC使用小技巧之用好mac电脑?的10个必知的小技巧!
很多朋友是不是都有这样的困惑,刚接手Mac电脑,无论是笔记本亦或是台式机,很是不方便,因为windows系统那种习惯已经先入为主了,今天就给大家普及一些小技巧. 当你看到这篇文章,不管你有没有mac电 ...
- plugin.go 源码阅读
, nil) } if c.client != nil { c.client.Close() } ...
- 获得指定数据库中指定块表中所有实体的id
该函数也使用外部指定图纸中的数据库中的块 Int getIdsByDwgBlkName(AcDbDatabase *pDwg, CString strBlkName, AcDbObjectIdArra ...
- laravel 分页和共多少条 加参数的分页链接
<div class="pagers "> <span class="fs pager">共 {{$trades->total() ...
- 遍历数组 foreach
package com.java.array; public class Myforeach { public static void main(String[] ARGS){ /* int arr[ ...
- Django_cookie_session
登录时候后台打印request.COOKIE 1.login页面正确登录的话,后台页面可以获取到浏览器携带的cookie的. 2.第一行的sessionid其实就是cookie值 3.session的 ...
- sum() 函数性能堪忧,列表降维有何良方?
本文原创并首发于公众号[Python猫],未经授权,请勿转载. 原文地址:https://mp.weixin.qq.com/s/mK1nav2vKykZaKw_TY-rtw Python 的内置函数 ...
- MIP技术进展月报第3期:MIP小姐姐听说,你想改改MIP官网?
一. 官网文档全部开源 MIP 是一项永久的开源的项目,提供持续优化的解决方案,当然官网也不能例外.从现在开始,任何人都可以在 MIP 官网贡献文档啦! GitHub 上,我们已经上传了 <官网 ...
- Android进阶加密-第1章-Android系统架构-读书笔记
第 1 章 Android 系统架构 1.1 Android 系统架构 Android 系统架构分为五层,从上到下依次是应用层.应用框架层.系统运行库层.硬件抽象层和 Linux 内核层. 应用层(S ...