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

前言

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

效果图

代码分析

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

1、自定义的MyBridgeWebView继承BridgeWebView

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

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

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

1、demo.html文件

  1. <html>
  2. <head>
  3. <meta content="text/html; charset=utf-8" http-equiv="content-type">
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  5. <title>
  6. js和java互调
  7. </title>
  8. </head>
  9.  
  10. <body>
  11.  
  12. </body>
  13. <!--用于解析json数据-->
  14. <script type="text/javascript" src="json2.js"></script>
  15. <script>
  16.  
  17. /*=====================================JSBridge==================================================*/
  18. //注册事件监听
  19. function connectWebViewJavascriptBridge(callback) {
  20. if (window.WebViewJavascriptBridge) {
  21. callback(WebViewJavascriptBridge)
  22. } else {
  23. document.addEventListener(
  24. 'WebViewJavascriptBridgeReady'
  25. , function() {
  26. callback(WebViewJavascriptBridge)
  27. },
  28. false
  29. );
  30. }
  31. }
  32. //注册回调函数,第一次连接时调用 初始化函数
  33. connectWebViewJavascriptBridge(function(bridge) {
  34. //初始化回调函数
  35. bridge.init(function(message, responseCallback) {
  36. var data = {
  37. 'Javascript Responds': 'js初始化响应!'
  38. };
  39. responseCallback(data);
  40.  
  41. });
  42.  
  43. //【Java调用的js方法】--用于js发送初始化后的消息给Java【由Java控制执行,在webviewClient的onPageFinished中执行】
  44. //java执行onPageFinished后,调用这个方法;然后js发送消息给java;java接收并处理后回调js的initData()方法
  45. bridge.registerHandler("sendMegToJavaFunctionInJs", function(data, responseCallback) {
  46. //发送消息(onPageFinished 可以理解为handle的message.what),告诉java,HTML页面已经加载完成,可以开始请求接口获取数据了
  47. window.WebViewJavascriptBridge.send(
  48. "onPageFinished"
  49. , function(responseData) {
  50. //responseData 可以理解为回调返回的字符串数据
  51. initData(responseData);
  52. }
  53. );
  54. responseCallback("js已发送消息给java");//java调用js方法,都要返回data数据,不过这里因为是初始化的操作,所以返回空值即可。
  55. });
  56.  
  57. })
  58.  
  59. /*=====webviewClient的onPageFinished执行后,js发送消息给java,然后java处理后回调js的方法======*/
  60. function initData(data){
  61. console.log("{initData}data="+data);
  62. //根据实际情况,进行赋值;或者不做任何处理
  63.  
  64. }
  65. </script>
  66.  
  67. </html>

2、MainActivity.java文件

  1. package com.why.project.mybridgewebviewdemo;
  2.  
  3. import android.annotation.TargetApi;
  4. import android.app.Activity;
  5. import android.content.Intent;
  6. import android.net.Uri;
  7. import android.os.Build;
  8. import android.os.Bundle;
  9. import android.support.v7.app.AppCompatActivity;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.widget.Toast;
  13.  
  14. import com.github.lzyzsd.jsbridge.BridgeHandler;
  15. import com.github.lzyzsd.jsbridge.CallBackFunction;
  16. import com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView;
  17. import com.why.project.mybridgewebviewdemo.customwebview.utils.WebviewGlobals;
  18.  
  19. public class MainActivity extends AppCompatActivity {
  20. private static final String TAG = MainActivity.class.getSimpleName();
  21.  
  22. /**jsBridgeWebview*/
  23. private MyBridgeWebView myWebView;
  24.  
  25. @Override
  26. protected void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. setContentView(R.layout.activity_main);
  29.  
  30. initViews();
  31. initDatas();
  32. initEvents();
  33. }
  34.  
  35. private void initViews() {
  36. myWebView = findViewById(R.id.web_view);
  37. }
  38.  
  39. private void initDatas() {
  40. myWebView.setDefaultHandler(new CustomBridgeHandler());//jsBridge
  41. //加载网址
  42. myWebView.loadLocalUrl("demo.html");
  43. initJsBridge();
  44.  
  45. //实现webview只可滑动不可点击【项目中需要用到的时候再解开注释】
  46. //http://blog.csdn.net/mjjmjc/article/details/47105001
  47. //http://blog.csdn.net/qq_32452623/article/details/52304628
  48. /*myWebView.setOnTouchListener(new View.OnTouchListener() {
  49. @Override
  50. public boolean onTouch(View view, MotionEvent motionEvent) {
  51. return true;
  52. }
  53. });*/
  54. }
  55.  
  56. /*=================================jsBridge=================================*/
  57. /**
  58. * 自定义BridgeHandler【用于接收html发送给Java的消息(通过data的值区分是哪个消息;function用于回调给js)】*/
  59. class CustomBridgeHandler implements BridgeHandler {
  60. @Override
  61. public void handler(String data, CallBackFunction function) {
  62. Log.i(TAG, "接收html发送给Java的消息(通过data的值区分是哪个消息):" + data);
  63. if(data.equals("onPageFinished")){//onPageFinished 跟html中的保持一致
  64. // TODO 请求接口获取数据
  65. if(function != null){
  66. function.onCallBack("这个是onPageFinished方法执行后js发送给java消息后,java回调给js的初始值");
  67. }
  68. }else{
  69.  
  70. }
  71. }
  72. }
  73.  
  74. //jsBridge 初始化一些事件监听
  75. private void initJsBridge(){
  76.  
  77. }
  78.  
  79. private void initEvents() {
  80.  
  81. }
  82.  
  83. }

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

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

  1. <html>
  2. <head>
  3. <meta content="text/html; charset=utf-8" http-equiv="content-type">
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  5. <title>
  6. js和java互调
  7. </title>
  8. </head>
  9.  
  10. <body>
  11. <p>
  12. <input type="text" id="show" style="width:100%;"/>
  13. </p>
  14. <p>
  15. <input type="button" id="enter" value="js发消息给Native" onclick="sendMegToJava();"
  16. />
  17. </p>
  18.  
  19. </body>
  20. <!--用于解析json数据-->
  21. <script type="text/javascript" src="json2.js"></script>
  22. <script>
  23.  
  24. //发消息给Native 按钮的点击事件
  25. //发送的消息是到BridgeHandler子类的handler方法中进行匹配
  26. function sendMegToJava() {
  27. //尽量使用json数据
  28. var message = "getNewData";//消息数据(可以直接是一个字符串,作为消息类型(比如getNewData);也可以是一个json字符串,根据key值进行判断类型)
  29. window.WebViewJavascriptBridge.send(
  30. message
  31. , function(responseData) {
  32. document.getElementById("show").value = responseData;
  33. }
  34. );
  35. }/*=====================================JSBridge==================================================*/
  36. //注册事件监听
  37. function connectWebViewJavascriptBridge(callback) {
  38. if (window.WebViewJavascriptBridge) {
  39. callback(WebViewJavascriptBridge)
  40. } else {
  41. document.addEventListener(
  42. 'WebViewJavascriptBridgeReady'
  43. , function() {
  44. callback(WebViewJavascriptBridge)
  45. },
  46. false
  47. );
  48. }
  49. }
  50. //注册回调函数,第一次连接时调用 初始化函数
  51. connectWebViewJavascriptBridge(function(bridge) {
  52. //初始化回调函数
  53. bridge.init(function(message, responseCallback) {
  54. var data = {
  55. 'Javascript Responds': 'js初始化响应!'
  56. };
  57. responseCallback(data);
  58.  
  59. });
  60. })
  61.  
  62. /*=====webviewClient的onPageFinished执行后,js发送消息给java,然后java处理后回调js的方法======*/
  63. function initData(data){
  64. console.log("{initData}data="+data);
  65. //根据实际情况,进行赋值;或者不做任何处理
  66. }
  67. </script>
  68.  
  69. </html>

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

  1. package com.why.project.mybridgewebviewdemo;
  2.  
  3. import android.annotation.TargetApi;
  4. import android.app.Activity;
  5. import android.content.Intent;
  6. import android.net.Uri;
  7. import android.os.Build;
  8. import android.os.Bundle;
  9. import android.support.v7.app.AppCompatActivity;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.widget.Toast;
  13.  
  14. import com.github.lzyzsd.jsbridge.BridgeHandler;
  15. import com.github.lzyzsd.jsbridge.CallBackFunction;
  16. import com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView;
  17. import com.why.project.mybridgewebviewdemo.customwebview.utils.WebviewGlobals;
  18.  
  19. public class MainActivity extends AppCompatActivity {
  20. private static final String TAG = MainActivity.class.getSimpleName();
  21.  
  22. /**jsBridgeWebview*/
  23. private MyBridgeWebView myWebView;
  24.  
  25. @Override
  26. protected void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. setContentView(R.layout.activity_main);
  29.  
  30. initViews();
  31. initDatas();
  32. initEvents();
  33. }
  34.  
  35. private void initViews() {
  36. myWebView = findViewById(R.id.web_view);
  37. }
  38.  
  39. private void initDatas() {
  40. myWebView.setDefaultHandler(new CustomBridgeHandler());//jsBridge
  41. //加载网址
  42. myWebView.loadLocalUrl("demo.html");
  43. initJsBridge();
  44.  
  45. //实现webview只可滑动不可点击【项目中需要用到的时候再解开注释】
  46. //http://blog.csdn.net/mjjmjc/article/details/47105001
  47. //http://blog.csdn.net/qq_32452623/article/details/52304628
  48. /*myWebView.setOnTouchListener(new View.OnTouchListener() {
  49. @Override
  50. public boolean onTouch(View view, MotionEvent motionEvent) {
  51. return true;
  52. }
  53. });*/
  54. }
  55.  
  56. /*=================================jsBridge=================================*/
  57. /**
  58. * 自定义BridgeHandler【用于接收html发送给Java的消息(通过data的值区分是哪个消息;function用于回调给js)】*/
  59. class CustomBridgeHandler implements BridgeHandler {
  60. @Override
  61. public void handler(String data, CallBackFunction function) {
  62. Log.i(TAG, "接收html发送给Java的消息(通过data的值区分是哪个消息):" + data);
  63. if(data.equals("onPageFinished")){//onPageFinished 跟html中的保持一致
  64. // TODO 请求接口获取数据
  65. if(function != null){
  66. function.onCallBack("这个是onPageFinished方法执行后js发送给java消息后,java回调给js的初始值");
  67. }
  68. }else{
  69. if(data.equals("getNewData")){
  70. // TODO 请求接口获取数据
  71. if(function != null){
  72. function.onCallBack("这个是js发送给java消息后返回的数据");
  73. }
  74. }
  75. }
  76. }
  77. }
  78.  
  79. //jsBridge 初始化一些事件监听
  80. private void initJsBridge(){
  81. }
  82.  
  83. }

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

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

  1. <html>
  2. <head>
  3. <meta content="text/html; charset=utf-8" http-equiv="content-type">
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  5. <title>
  6. js和java互调
  7. </title>
  8. </head>
  9.  
  10. <body>
  11. <p>
  12. <input type="text" id="show" style="width:100%;"/>
  13. </p>
  14. <p>
  15. <input type="button" id="enter1" value="js调用Native的方法" onclick="callJavaMethod();"
  16. />
  17. </p>
  18. </body>
  19. <!--用于解析json数据-->
  20. <script type="text/javascript" src="json2.js"></script>
  21. <script>
  22.  
  23. //调用Native方法 按钮的点击事件
  24. //调用的java方法需要在activity界面中进行声明,参考initJsBridge()方法中的声明方法
  25. function callJavaMethod() {
  26. //尽量使用json数据
  27. var dataObj = new Object();
  28. dataObj.id = ;
  29. dataObj.title = "这是一个标题"
  30. dataObj.isNew = true;
  31. var dataObjStr = JSON.stringify(dataObj);
  32.  
  33. //functionInJava : 在Activity界面的initJsBridge()中声明的方法
  34. window.WebViewJavascriptBridge.callHandler(
  35. 'functionInJava'
  36. , {'param': dataObjStr}
  37. , function(responseData) {
  38. document.getElementById("show").value = responseData;
  39. }
  40. );
  41. }/*=====================================JSBridge==================================================*/
  42. //注册事件监听
  43. function connectWebViewJavascriptBridge(callback) {
  44. if (window.WebViewJavascriptBridge) {
  45. callback(WebViewJavascriptBridge)
  46. } else {
  47. document.addEventListener(
  48. 'WebViewJavascriptBridgeReady'
  49. , function() {
  50. callback(WebViewJavascriptBridge)
  51. },
  52. false
  53. );
  54. }
  55. }
  56. //注册回调函数,第一次连接时调用 初始化函数
  57. connectWebViewJavascriptBridge(function(bridge) {
  58. //初始化回调函数
  59. bridge.init(function(message, responseCallback) {
  60. var data = {
  61. 'Javascript Responds': 'js初始化响应!'
  62. };
  63. responseCallback(data);
  64.  
  65. });
  66.  
  67. //【Java调用的js方法】--用于js发送初始化后的消息给Java【由Java控制执行,在webviewClient的onPageFinished中执行】
  68. //java执行onPageFinished后,调用这个方法;然后js发送消息给java;java接收并处理后回调js的initData()方法
  69. bridge.registerHandler("sendMegToJavaFunctionInJs", function(data, responseCallback) {
  70. //发送消息(onPageFinished 可以理解为handle的message.what),告诉java,HTML页面已经加载完成,可以开始请求接口获取数据了
  71. window.WebViewJavascriptBridge.send(
  72. "onPageFinished"
  73. , function(responseData) {
  74. //responseData 可以理解为回调返回的字符串数据
  75. initData(responseData);
  76. }
  77. );
  78. responseCallback("js已发送消息给java");//java调用js方法,都要返回data数据,不过这里因为是初始化的操作,所以返回空值即可。
  79. });
  80. })
  81.  
  82. /*=====webviewClient的onPageFinished执行后,js发送消息给java,然后java处理后回调js的方法======*/
  83. function initData(data){
  84. console.log("{initData}data="+data);
  85. //根据实际情况,进行赋值;或者不做任何处理
  86. }
  87. </script>
  88.  
  89. </html>

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

  1. package com.why.project.mybridgewebviewdemo;
  2.  
  3. import android.annotation.TargetApi;
  4. import android.app.Activity;
  5. import android.content.Intent;
  6. import android.net.Uri;
  7. import android.os.Build;
  8. import android.os.Bundle;
  9. import android.support.v7.app.AppCompatActivity;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.widget.Toast;
  13.  
  14. import com.github.lzyzsd.jsbridge.BridgeHandler;
  15. import com.github.lzyzsd.jsbridge.CallBackFunction;
  16. import com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView;
  17. import com.why.project.mybridgewebviewdemo.customwebview.utils.WebviewGlobals;
  18.  
  19. public class MainActivity extends AppCompatActivity {
  20. private static final String TAG = MainActivity.class.getSimpleName();
  21.  
  22. /**jsBridgeWebview*/
  23. private MyBridgeWebView myWebView;
  24.  
  25. @Override
  26. protected void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. setContentView(R.layout.activity_main);
  29.  
  30. initViews();
  31. initDatas();
  32. initEvents();
  33. }
  34.  
  35. private void initViews() {
  36. myWebView = findViewById(R.id.web_view);
  37. }
  38.  
  39. private void initDatas() {
  40. myWebView.setDefaultHandler(new CustomBridgeHandler());//jsBridge
  41. //加载网址
  42. myWebView.loadLocalUrl("demo.html");
  43. initJsBridge();
  44.  
  45. //实现webview只可滑动不可点击【项目中需要用到的时候再解开注释】
  46. //http://blog.csdn.net/mjjmjc/article/details/47105001
  47. //http://blog.csdn.net/qq_32452623/article/details/52304628
  48. /*myWebView.setOnTouchListener(new View.OnTouchListener() {
  49. @Override
  50. public boolean onTouch(View view, MotionEvent motionEvent) {
  51. return true;
  52. }
  53. });*/
  54. }
  55.  
  56. /*=================================jsBridge=================================*/
  57. /**
  58. * 自定义BridgeHandler【用于接收html发送给Java的消息(通过data的值区分是哪个消息;function用于回调给js)】*/
  59. class CustomBridgeHandler implements BridgeHandler {
  60. @Override
  61. public void handler(String data, CallBackFunction function) {
  62. Log.i(TAG, "接收html发送给Java的消息(通过data的值区分是哪个消息):" + data);
  63. if(data.equals("onPageFinished")){//onPageFinished 跟html中的保持一致
  64. // TODO 请求接口获取数据
  65. if(function != null){
  66. function.onCallBack("这个是onPageFinished方法执行后js发送给java消息后,java回调给js的初始值");
  67. }
  68. }else{
  69. }
  70. }
  71. }
  72.  
  73. //jsBridge 初始化一些事件监听
  74. private void initJsBridge(){
  75. //【js调用Java的方法】必须和js中的调用函数名相同,注册具体执行函数,类似java实现类。
  76. myWebView.registerHandler("functionInJava", new BridgeHandler() {
  77. @Override
  78. public void handler(String data, CallBackFunction function) {
  79. Log.i(TAG, "接收html发送给Java的数据:" + data);
  80.  
  81. String callbackData = "这个是js调用java方法后返回的数据";
  82. function.onCallBack(callbackData);
  83. }
  84. });
  85. }
  86.  
  87. private void initEvents() {
  88. }
  89.  
  90. }

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

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

  1. <html>
  2. <head>
  3. <meta content="text/html; charset=utf-8" http-equiv="content-type">
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  5. <title>
  6. js和java互调
  7. </title>
  8. </head>
  9.  
  10. <body>
  11. <p>
  12. <input type="text" id="show" style="width:100%;"/>
  13. </p>
  14.  
  15. </body>
  16. <!--用于解析json数据-->
  17. <script type="text/javascript" src="json2.js"></script>
  18. <script>
  19.  
  20. //java调用js方法实际执行的方法
  21. function handleJavaData(dataObj){
  22. document.getElementById("show").value = "用户名=" + dataObj.username + ";密码=" + dataObj.password;
  23. return "登录成功呢";
  24. }
  25.  
  26. /*=====================================JSBridge==================================================*/
  27. //注册事件监听
  28. function connectWebViewJavascriptBridge(callback) {
  29. if (window.WebViewJavascriptBridge) {
  30. callback(WebViewJavascriptBridge)
  31. } else {
  32. document.addEventListener(
  33. 'WebViewJavascriptBridgeReady'
  34. , function() {
  35. callback(WebViewJavascriptBridge)
  36. },
  37. false
  38. );
  39. }
  40. }
  41. //注册回调函数,第一次连接时调用 初始化函数
  42. connectWebViewJavascriptBridge(function(bridge) {
  43. //初始化回调函数
  44. bridge.init(function(message, responseCallback) {
  45. var data = {
  46. 'Javascript Responds': 'js初始化响应!'
  47. };
  48. responseCallback(data);
  49.  
  50. });
  51.  
  52. //【Java调用的js方法】--用于js发送初始化后的消息给Java【由Java控制执行,在webviewClient的onPageFinished中执行】
  53. //java执行onPageFinished后,调用这个方法;然后js发送消息给java;java接收并处理后回调js的initData()方法
  54. bridge.registerHandler("sendMegToJavaFunctionInJs", function(data, responseCallback) {
  55. //发送消息(onPageFinished 可以理解为handle的message.what),告诉java,HTML页面已经加载完成,可以开始请求接口获取数据了
  56. window.WebViewJavascriptBridge.send(
  57. "onPageFinished"
  58. , function(responseData) {
  59. //responseData 可以理解为回调返回的字符串数据
  60. initData(responseData);
  61. }
  62. );
  63. responseCallback("js已发送消息给java");//java调用js方法,都要返回data数据,不过这里因为是初始化的操作,所以返回空值即可。
  64. });
  65.  
  66. /*============================自定义java调用的js方法声明【根据实际情况声明方法】===========================================*/
  67. //【Java调用的js方法】
  68. bridge.registerHandler("functionInJs", function(data, responseCallback) {
  69. //JSON.parse(jsonstr); //方法一:可以将json字符串转换成json对象
  70. //JSON.stringify(jsonobj); //方法二:可以将json对象转换成json对符串
  71.  
  72. var dataObj = JSON.parse(data);//将发送过来的数据转为json对象
  73.  
  74. //一般都有一个配套的js方法,用于处理接收到的数据
  75. var responseData = handleJavaData(dataObj);
  76.  
  77. responseCallback(responseData);
  78. });
  79. })
  80.  
  81. /*=====webviewClient的onPageFinished执行后,js发送消息给java,然后java处理后回调js的方法======*/
  82. function initData(data){
  83. console.log("{initData}data="+data);
  84. //根据实际情况,进行赋值;或者不做任何处理
  85. }
  86. </script>
  87.  
  88. </html>

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

  1. package com.why.project.mybridgewebviewdemo;
  2.  
  3. import android.annotation.TargetApi;
  4. import android.app.Activity;
  5. import android.content.Intent;
  6. import android.net.Uri;
  7. import android.os.Build;
  8. import android.os.Bundle;
  9. import android.support.v7.app.AppCompatActivity;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.widget.Toast;
  13.  
  14. import com.github.lzyzsd.jsbridge.BridgeHandler;
  15. import com.github.lzyzsd.jsbridge.CallBackFunction;
  16. import com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView;
  17. import com.why.project.mybridgewebviewdemo.customwebview.utils.WebviewGlobals;
  18.  
  19. public class MainActivity extends AppCompatActivity {
  20. private static final String TAG = MainActivity.class.getSimpleName();
  21.  
  22. /**jsBridgeWebview*/
  23. private MyBridgeWebView myWebView;
  24.  
  25. @Override
  26. protected void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. setContentView(R.layout.activity_main);
  29.  
  30. initViews();
  31. initDatas();
  32. initEvents();
  33. }
  34.  
  35. private void initViews() {
  36. myWebView = findViewById(R.id.web_view);
  37. }
  38.  
  39. private void initDatas() {
  40. myWebView.setDefaultHandler(new CustomBridgeHandler());//jsBridge
  41. //加载网址
  42. myWebView.loadLocalUrl("demo.html");
  43. initJsBridge();
  44.  
  45. //实现webview只可滑动不可点击【项目中需要用到的时候再解开注释】
  46. //http://blog.csdn.net/mjjmjc/article/details/47105001
  47. //http://blog.csdn.net/qq_32452623/article/details/52304628
  48. /*myWebView.setOnTouchListener(new View.OnTouchListener() {
  49. @Override
  50. public boolean onTouch(View view, MotionEvent motionEvent) {
  51. return true;
  52. }
  53. });*/
  54. }
  55.  
  56. /*=================================jsBridge=================================*/
  57. /**
  58. * 自定义BridgeHandler【用于接收html发送给Java的消息(通过data的值区分是哪个消息;function用于回调给js)】*/
  59. class CustomBridgeHandler implements BridgeHandler {
  60. @Override
  61. public void handler(String data, CallBackFunction function) {
  62. Log.i(TAG, "接收html发送给Java的消息(通过data的值区分是哪个消息):" + data);
  63. if(data.equals("onPageFinished")){//onPageFinished 跟html中的保持一致
  64. // TODO 请求接口获取数据
  65. if(function != null){
  66. function.onCallBack("这个是onPageFinished方法执行后js发送给java消息后,java回调给js的初始值");
  67. }
  68. }else{
  69. }
  70. }
  71. }
  72.  
  73. //jsBridge 初始化一些事件监听
  74. private void initJsBridge(){
  75. }
  76.  
  77. private void initEvents() {
  78. findViewById(R.id.btn_calljsfunction).setOnClickListener(new View.OnClickListener() {
  79. @Override
  80. public void onClick(View view) {
  81. //Java调用js的方法
  82. //发送给js的参数,使用Json格式
  83. String params = "{\"username\":\"why\",\"password\":\"123456\"}";
  84. myWebView.callHandler("functionInJs",params, new CallBackFunction() {
  85. @Override
  86. public void onCallBack(String data) {
  87. // TODO Auto-generated method stub
  88. //处理html返回给Java的数据
  89. Toast.makeText(MainActivity.this,data,Toast.LENGTH_SHORT).show();
  90. }
  91. });
  92. }
  93. });
  94. }
  95.  
  96. }

六、选择文件的功能

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

  1. <html>
  2. <head>
  3. <meta content="text/html; charset=utf-8" http-equiv="content-type">
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  5. <title>
  6. js和java互调
  7. </title>
  8. </head>
  9.  
  10. <body>
  11. <p>
  12. <input type="file" value="打开文件" />
  13. </p>
  14. </body>
  15. <script>
  16. </script>
  17.  
  18. </html>

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

  1. package com.why.project.mybridgewebviewdemo;
  2.  
  3. import android.annotation.TargetApi;
  4. import android.app.Activity;
  5. import android.content.Intent;
  6. import android.net.Uri;
  7. import android.os.Build;
  8. import android.os.Bundle;
  9. import android.support.v7.app.AppCompatActivity;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.widget.Toast;
  13.  
  14. import com.github.lzyzsd.jsbridge.BridgeHandler;
  15. import com.github.lzyzsd.jsbridge.CallBackFunction;
  16. import com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView;
  17. import com.why.project.mybridgewebviewdemo.customwebview.utils.WebviewGlobals;
  18.  
  19. public class MainActivity extends AppCompatActivity {
  20. private static final String TAG = MainActivity.class.getSimpleName();
  21.  
  22. /**jsBridgeWebview*/
  23. private MyBridgeWebView myWebView;
  24.  
  25. @Override
  26. protected void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. setContentView(R.layout.activity_main);
  29.  
  30. initViews();
  31. initDatas();
  32. initEvents();
  33. }
  34.  
  35. private void initViews() {
  36. myWebView = findViewById(R.id.web_view);
  37. }
  38.  
  39. private void initDatas() {
  40. myWebView.setDefaultHandler(new CustomBridgeHandler());//jsBridge
  41. //加载网址
  42. myWebView.loadLocalUrl("demo.html");
  43. initJsBridge();
  44.  
  45. //实现webview只可滑动不可点击【项目中需要用到的时候再解开注释】
  46. //http://blog.csdn.net/mjjmjc/article/details/47105001
  47. //http://blog.csdn.net/qq_32452623/article/details/52304628
  48. /*myWebView.setOnTouchListener(new View.OnTouchListener() {
  49. @Override
  50. public boolean onTouch(View view, MotionEvent motionEvent) {
  51. return true;
  52. }
  53. });*/
  54. }
  55.  
  56. /*=================================jsBridge=================================*/
  57. /**
  58. * 自定义BridgeHandler【用于接收html发送给Java的消息(通过data的值区分是哪个消息;function用于回调给js)】*/
  59. class CustomBridgeHandler implements BridgeHandler {
  60. @Override
  61. public void handler(String data, CallBackFunction function) {
  62. Log.i(TAG, "接收html发送给Java的消息(通过data的值区分是哪个消息):" + data);
  63. if(data.equals("onPageFinished")){//onPageFinished 跟html中的保持一致
  64. // TODO 请求接口获取数据
  65. if(function != null){
  66. function.onCallBack("这个是onPageFinished方法执行后js发送给java消息后,java回调给js的初始值");
  67. }
  68. }else{
  69. }
  70. }
  71. }
  72.  
  73. //jsBridge 初始化一些事件监听
  74. private void initJsBridge(){
  75. }
  76.  
  77. private void initEvents() {
  78. }
  79.  
  80. /*=========================================实现webview调用选择文件的功能==============================================*/
  81. @Override
  82. public void onActivityResult(int requestCode, int resultCode, Intent data) {
  83. super.onActivityResult(requestCode, resultCode, data);
  84. Log.w(TAG, "{onActivityResult}resultCode="+resultCode);
  85. Log.w(TAG, "{onActivityResult}requestCode="+requestCode);
  86. Log.w(TAG, "{onActivityResult}data="+data);
  87. if (resultCode == Activity.RESULT_OK) {
  88. //webview界面调用打开本地文件管理器选择文件的回调
  89. if (requestCode == WebviewGlobals.CHOOSE_FILE_REQUEST_CODE ) {
  90. Uri result = data == null ? null : data.getData();
  91. Log.w(TAG,"{onActivityResult}文件路径地址:" + result.toString());
  92.  
  93. //如果mUploadMessage或者mUploadCallbackAboveL不为空,代表是触发input[type]类型的标签
  94. if (null != myWebView.getMyBridgeWebChromeClient().getmUploadMessage() || null != myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL()) {
  95. if (myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL() != null) {
  96. onActivityResultAboveL(requestCode, data);//5.0++
  97. } else if (myWebView.getMyBridgeWebChromeClient().getmUploadMessage() != null) {
  98. myWebView.getMyBridgeWebChromeClient().getmUploadMessage().onReceiveValue(result);//将文件路径返回去,填充到input中
  99. myWebView.getMyBridgeWebChromeClient().setmUploadMessage(null);
  100. }
  101. }else{
  102. //此处代码是处理通过js方法触发的情况
  103. Log.w(TAG,"{onActivityResult}文件路径地址(js):" + result.toString());
  104. }
  105. }
  106. }else if(resultCode == RESULT_CANCELED){//resultCode == RESULT_CANCELED 解决不选择文件,直接返回后无法再次点击的问题
  107. if (myWebView.getMyBridgeWebChromeClient().getmUploadMessage() != null) {
  108. myWebView.getMyBridgeWebChromeClient().getmUploadMessage().onReceiveValue(null);
  109. myWebView.getMyBridgeWebChromeClient().setmUploadMessage(null);
  110. }
  111. if (myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL() != null) {
  112. myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL().onReceiveValue(null);
  113. myWebView.getMyBridgeWebChromeClient().setmUploadCallbackAboveL(null);
  114. }
  115. }
  116. }
  117.  
  118. //5.0以上版本,由于api不一样,要单独处理
  119. @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  120. private void onActivityResultAboveL(int requestCode, Intent data) {
  121.  
  122. if (myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL() == null) {
  123. return;
  124. }
  125. Uri result = null;
  126. if (requestCode == WebviewGlobals.CHOOSE_FILE_REQUEST_CODE) {//打开本地文件管理器选择图片
  127. result = data == null ? null : data.getData();
  128. }
  129. Log.w(TAG,"{onActivityResultAboveL}文件路径地址:"+result.toString());
  130. myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL().onReceiveValue(new Uri[]{result});//将文件路径返回去,填充到input中
  131. myWebView.getMyBridgeWebChromeClient().setmUploadCallbackAboveL(null);
  132. return;
  133. }
  134.  
  135. }

使用步骤

一、项目组织结构图

注意事项:

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

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

二、导入步骤

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

  1. apply plugin: 'com.android.application'
  2.  
  3. android {
  4. compileSdkVersion 27
  5. defaultConfig {
  6. applicationId "com.why.project.mybridgewebviewdemo"
  7. minSdkVersion 16
  8. targetSdkVersion 27
  9. versionCode 1
  10. versionName "1.0"
  11. testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
  12. }
  13. buildTypes {
  14. release {
  15. minifyEnabled false
  16. proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
  17. }
  18. }
  19. }
  20. //jsbridge
  21. repositories{
  22. //jsBridge
  23. maven { url "https://jitpack.io" }
  24. }
  25.  
  26. dependencies {
  27. implementation fileTree(dir: 'libs', include: ['*.jar'])
  28. implementation 'com.android.support:appcompat-v7:27.1.1'
  29. implementation 'com.android.support.constraint:constraint-layout:1.1.2'
  30. testImplementation 'junit:junit:4.12'
  31. androidTestImplementation 'com.android.support.test:runner:1.0.2'
  32. androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
  33.  
  34. //jsBridge
  35. compile 'com.github.lzyzsd:jsbridge:1.0.4'
  36. }

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

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

  1. <html>
  2. <head>
  3. <meta content="text/html; charset=utf-8" http-equiv="content-type">
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  5. <title>
  6. js和java互调
  7. </title>
  8. </head>
  9.  
  10. <body>
  11. <p>
  12. <input type="text" id="show" style="width:100%;"/>
  13. </p>
  14. <p>
  15. <input type="button" id="enter" value="js发消息给Native" onclick="sendMegToJava();"
  16. />
  17. </p>
  18. <p>
  19. <input type="button" id="enter1" value="js调用Native的方法" onclick="callJavaMethod();"
  20. />
  21. </p>
  22. <p>
  23. <input type="file" value="打开文件" />
  24. </p>
  25. </body>
  26. <!--用于解析json数据-->
  27. <script type="text/javascript" src="json2.js"></script>
  28. <script>
  29.  
  30. //发消息给Native 按钮的点击事件
  31. //发送的消息是到BridgeHandler子类的handler方法中进行匹配
  32. function sendMegToJava() {
  33. //尽量使用json数据
  34. var message = "getNewData";//消息数据(可以直接是一个字符串,作为消息类型(比如getNewData);也可以是一个json字符串,根据key值进行判断类型)
  35. window.WebViewJavascriptBridge.send(
  36. message
  37. , function(responseData) {
  38. document.getElementById("show").value = responseData;
  39. }
  40. );
  41. }
  42.  
  43. //调用Native方法 按钮的点击事件
  44. //调用的java方法需要在activity界面中进行声明,参考initJsBridge()方法中的声明方法
  45. function callJavaMethod() {
  46. //尽量使用json数据
  47. var dataObj = new Object();
  48. dataObj.id = 153273;
  49. dataObj.title = "这是一个标题"
  50. dataObj.isNew = true;
  51. var dataObjStr = JSON.stringify(dataObj);
  52.  
  53. //functionInJava : 在Activity界面的initJsBridge()中声明的方法
  54. window.WebViewJavascriptBridge.callHandler(
  55. 'functionInJava'
  56. , {'param': dataObjStr}
  57. , function(responseData) {
  58. document.getElementById("show").value = responseData;
  59. }
  60. );
  61. }
  62.  
  63. //java调用js方法实际执行的方法
  64. function handleJavaData(dataObj){
  65. document.getElementById("show").value = "用户名=" + dataObj.username + ";密码=" + dataObj.password;
  66. return "登录成功呢";
  67. }
  68.  
  69. /*=====================================JSBridge==================================================*/
  70. //注册事件监听
  71. function connectWebViewJavascriptBridge(callback) {
  72. if (window.WebViewJavascriptBridge) {
  73. callback(WebViewJavascriptBridge)
  74. } else {
  75. document.addEventListener(
  76. 'WebViewJavascriptBridgeReady'
  77. , function() {
  78. callback(WebViewJavascriptBridge)
  79. },
  80. false
  81. );
  82. }
  83. }
  84. //注册回调函数,第一次连接时调用 初始化函数
  85. connectWebViewJavascriptBridge(function(bridge) {
  86. //初始化回调函数
  87. bridge.init(function(message, responseCallback) {
  88. var data = {
  89. 'Javascript Responds': 'js初始化响应!'
  90. };
  91. responseCallback(data);
  92.  
  93. });
  94.  
  95. //【Java调用的js方法】--用于js发送初始化后的消息给Java【由Java控制执行,在webviewClient的onPageFinished中执行】
  96. //java执行onPageFinished后,调用这个方法;然后js发送消息给java;java接收并处理后回调js的initData()方法
  97. bridge.registerHandler("sendMegToJavaFunctionInJs", function(data, responseCallback) {
  98. //发送消息(onPageFinished 可以理解为handle的message.what),告诉java,HTML页面已经加载完成,可以开始请求接口获取数据了
  99. window.WebViewJavascriptBridge.send(
  100. "onPageFinished"
  101. , function(responseData) {
  102. //responseData 可以理解为回调返回的字符串数据
  103. initData(responseData);
  104. }
  105. );
  106. responseCallback("js已发送消息给java");//java调用js方法,都要返回data数据,不过这里因为是初始化的操作,所以返回空值即可。
  107. });
  108.  
  109. /*============================自定义java调用的js方法声明【根据实际情况声明方法】===========================================*/
  110. //【Java调用的js方法】
  111. bridge.registerHandler("functionInJs", function(data, responseCallback) {
  112. //JSON.parse(jsonstr); //方法一:可以将json字符串转换成json对象
  113. //JSON.stringify(jsonobj); //方法二:可以将json对象转换成json对符串
  114.  
  115. var dataObj = JSON.parse(data);//将发送过来的数据转为json对象
  116.  
  117. //一般都有一个配套的js方法,用于处理接收到的数据
  118. var responseData = handleJavaData(dataObj);
  119.  
  120. responseCallback(responseData);
  121. });
  122. })
  123.  
  124. /*=====webviewClient的onPageFinished执行后,js发送消息给java,然后java处理后回调js的方法======*/
  125. function initData(data){
  126. console.log("{initData}data="+data);
  127. //根据实际情况,进行赋值;或者不做任何处理
  128. document.getElementById("show").value = data;
  129. }
  130. </script>
  131.  
  132. </html>

demo.html

3、将customwebview包复制到项目中

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

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

mybridgewebview_progress_dialog_img_drawable.xml

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

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

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- WebView使用的进度加载对话框布局文件 -->
  3. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:id="@+id/dialog_view"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent">
  7.  
  8. <!-- 自定义圆形进度条 -->
  9. <!-- android:indeterminateDrawable自定义动画图标 -->
  10. <ProgressBar
  11. android:id="@+id/loadProgressBar"
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"
  14. android:layout_centerInParent="true"
  15. android:layout_marginLeft="5dp"
  16. android:layout_marginRight="5dp"
  17. android:indeterminateDrawable="@drawable/mybridgewebview_progress_dialog_img_drawable"
  18. />
  19.  
  20. </RelativeLayout>

mybridgewebview_dialog_webviewprogress.xml

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

  1. <resources>
  2.  
  3. <!-- Base application theme. -->
  4. <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  5. <!-- Customize your theme here. -->
  6. <item name="colorPrimary">@color/colorPrimary</item>
  7. <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
  8. <item name="colorAccent">@color/colorAccent</item>
  9. </style>
  10.  
  11. <!-- ==================MyBridgeWebView========网页加载时的进度对话框========================== -->
  12. <style name="mybridgewebview_loading_style" parent="android:style/Theme.Dialog">
  13. <!-- Dialog的windowFrame框为无 -->
  14. <item name="android:windowFrame">@null</item>
  15. <!-- 是否显示title -->
  16. <item name="android:windowNoTitle">true</item>
  17. <!-- 是否浮现在activity之上 -->
  18. <item name="android:windowIsFloating">true</item>
  19. <!-- 设置dialog的背景:#00000000透明色 -->
  20. <item name="android:windowBackground">@android:color/transparent</item>
  21. <!-- 半透明 -->
  22. <item name="android:windowIsTranslucent">true</item>
  23. <!-- 背景变灰:整个屏幕变灰,配合setCanceledOnTouchOutside(false) -->
  24. <item name="android:backgroundDimEnabled">false</item>
  25. <!-- 对话框是否有遮盖 -->
  26. <item name="android:windowContentOverlay">@null</item>
  27. </style>
  28.  
  29. </resources>

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

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.why.project.mybridgewebviewdemo">
  4.  
  5. <!-- ======================(MyBridgeWebView)========================== -->
  6. <!-- 允许程序打开网络套接字 -->
  7. <uses-permission android:name="android.permission.INTERNET"/>
  8.  
  9. <application
  10. android:allowBackup="true"
  11. android:icon="@mipmap/ic_launcher"
  12. android:label="@string/app_name"
  13. android:roundIcon="@mipmap/ic_launcher_round"
  14. android:supportsRtl="true"
  15. android:theme="@style/AppTheme">
  16. <activity android:name=".MainActivity">
  17. <intent-filter>
  18. <action android:name="android.intent.action.MAIN"/>
  19.  
  20. <category android:name="android.intent.category.LAUNCHER"/>
  21. </intent-filter>
  22. </activity>
  23. </application>
  24.  
  25. </manifest>

三、使用方法

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

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:id="@+id/activity_main"
  6. android:layout_width="match_parent"
  7. android:layout_height="match_parent"
  8. android:background="#bbbcbc"
  9. android:orientation="vertical">
  10.  
  11. <!-- button 演示Java调用web -->
  12. <Button
  13. android:id="@+id/btn_calljsfunction"
  14. android:layout_width="match_parent"
  15. android:layout_height="48dp"
  16. android:text="Native调用Js方法"
  17. />
  18.  
  19. <com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView
  20. android:id="@+id/web_view"
  21. android:layout_width="match_parent"
  22. android:layout_height="match_parent"
  23. android:layout_weight="1"/>
  24.  
  25. </LinearLayout>

在Activity中使用如下

  1. package com.why.project.mybridgewebviewdemo;
  2.  
  3. import android.annotation.TargetApi;
  4. import android.app.Activity;
  5. import android.content.Intent;
  6. import android.net.Uri;
  7. import android.os.Build;
  8. import android.os.Bundle;
  9. import android.support.v7.app.AppCompatActivity;
  10. import android.util.Log;
  11. import android.view.View;
  12. import android.widget.Toast;
  13.  
  14. import com.github.lzyzsd.jsbridge.BridgeHandler;
  15. import com.github.lzyzsd.jsbridge.CallBackFunction;
  16. import com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView;
  17. import com.why.project.mybridgewebviewdemo.customwebview.utils.WebviewGlobals;
  18.  
  19. public class MainActivity extends AppCompatActivity {
  20. private static final String TAG = MainActivity.class.getSimpleName();
  21.  
  22. /**jsBridgeWebview*/
  23. private MyBridgeWebView myWebView;
  24.  
  25. @Override
  26. protected void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. setContentView(R.layout.activity_main);
  29.  
  30. initViews();
  31. initDatas();
  32. initEvents();
  33. }
  34.  
  35. private void initViews() {
  36. myWebView = findViewById(R.id.web_view);
  37. }
  38.  
  39. private void initDatas() {
  40. myWebView.setDefaultHandler(new CustomBridgeHandler());//jsBridge
  41. //加载网址
  42. myWebView.loadLocalUrl("demo.html");
  43. initJsBridge();
  44.  
  45. //实现webview只可滑动不可点击【项目中需要用到的时候再解开注释】
  46. //http://blog.csdn.net/mjjmjc/article/details/47105001
  47. //http://blog.csdn.net/qq_32452623/article/details/52304628
  48. /*myWebView.setOnTouchListener(new View.OnTouchListener() {
  49. @Override
  50. public boolean onTouch(View view, MotionEvent motionEvent) {
  51. return true;
  52. }
  53. });*/
  54. }
  55.  
  56. /*=================================jsBridge=================================*/
  57. /**
  58. * 自定义BridgeHandler【用于接收html发送给Java的消息(通过data的值区分是哪个消息;function用于回调给js)】*/
  59. class CustomBridgeHandler implements BridgeHandler {
  60. @Override
  61. public void handler(String data, CallBackFunction function) {
  62. Log.i(TAG, "接收html发送给Java的消息(通过data的值区分是哪个消息):" + data);
  63. if(data.equals("onPageFinished")){//onPageFinished 跟html中的保持一致
  64. // TODO 请求接口获取数据
  65. if(function != null){
  66. function.onCallBack("这个是onPageFinished方法执行后js发送给java消息后,java回调给js的初始值");
  67. }
  68. }else{
  69. if(data.equals("getNewData")){
  70. // TODO 请求接口获取数据
  71. if(function != null){
  72. function.onCallBack("这个是js发送给java消息后返回的数据");
  73. }
  74. }
  75. }
  76. }
  77. }
  78.  
  79. //jsBridge 初始化一些事件监听
  80. private void initJsBridge(){
  81. //【js调用Java的方法】必须和js中的调用函数名相同,注册具体执行函数,类似java实现类。
  82. myWebView.registerHandler("functionInJava", new BridgeHandler() {
  83. @Override
  84. public void handler(String data, CallBackFunction function) {
  85. Log.i(TAG, "接收html发送给Java的数据:" + data);
  86.  
  87. String callbackData = "这个是js调用java方法后返回的数据";
  88. function.onCallBack(callbackData);
  89. }
  90. });
  91. }
  92.  
  93. private void initEvents() {
  94. findViewById(R.id.btn_calljsfunction).setOnClickListener(new View.OnClickListener() {
  95. @Override
  96. public void onClick(View view) {
  97. //Java调用js的方法
  98. //发送给js的参数,使用Json格式
  99. String params = "{\"username\":\"why\",\"password\":\"123456\"}";
  100. myWebView.callHandler("functionInJs",params, new CallBackFunction() {
  101. @Override
  102. public void onCallBack(String data) {
  103. // TODO Auto-generated method stub
  104. //处理html返回给Java的数据
  105. Toast.makeText(MainActivity.this,data,Toast.LENGTH_SHORT).show();
  106. }
  107. });
  108. }
  109. });
  110. }
  111.  
  112. /*=========================================实现webview调用选择文件的功能==============================================*/
  113. @Override
  114. public void onActivityResult(int requestCode, int resultCode, Intent data) {
  115. super.onActivityResult(requestCode, resultCode, data);
  116. Log.w(TAG, "{onActivityResult}resultCode="+resultCode);
  117. Log.w(TAG, "{onActivityResult}requestCode="+requestCode);
  118. Log.w(TAG, "{onActivityResult}data="+data);
  119. if (resultCode == Activity.RESULT_OK) {
  120. //webview界面调用打开本地文件管理器选择文件的回调
  121. if (requestCode == WebviewGlobals.CHOOSE_FILE_REQUEST_CODE ) {
  122. Uri result = data == null ? null : data.getData();
  123. Log.w(TAG,"{onActivityResult}文件路径地址:" + result.toString());
  124.  
  125. //如果mUploadMessage或者mUploadCallbackAboveL不为空,代表是触发input[type]类型的标签
  126. if (null != myWebView.getMyBridgeWebChromeClient().getmUploadMessage() || null != myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL()) {
  127. if (myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL() != null) {
  128. onActivityResultAboveL(requestCode, data);//5.0++
  129. } else if (myWebView.getMyBridgeWebChromeClient().getmUploadMessage() != null) {
  130. myWebView.getMyBridgeWebChromeClient().getmUploadMessage().onReceiveValue(result);//将文件路径返回去,填充到input中
  131. myWebView.getMyBridgeWebChromeClient().setmUploadMessage(null);
  132. }
  133. }else{
  134. //此处代码是处理通过js方法触发的情况
  135. Log.w(TAG,"{onActivityResult}文件路径地址(js):" + result.toString());
  136. }
  137. }
  138. }else if(resultCode == RESULT_CANCELED){//resultCode == RESULT_CANCELED 解决不选择文件,直接返回后无法再次点击的问题
  139. if (myWebView.getMyBridgeWebChromeClient().getmUploadMessage() != null) {
  140. myWebView.getMyBridgeWebChromeClient().getmUploadMessage().onReceiveValue(null);
  141. myWebView.getMyBridgeWebChromeClient().setmUploadMessage(null);
  142. }
  143. if (myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL() != null) {
  144. myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL().onReceiveValue(null);
  145. myWebView.getMyBridgeWebChromeClient().setmUploadCallbackAboveL(null);
  146. }
  147. }
  148. }
  149.  
  150. //5.0以上版本,由于api不一样,要单独处理
  151. @TargetApi(Build.VERSION_CODES.LOLLIPOP)
  152. private void onActivityResultAboveL(int requestCode, Intent data) {
  153.  
  154. if (myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL() == null) {
  155. return;
  156. }
  157. Uri result = null;
  158. if (requestCode == WebviewGlobals.CHOOSE_FILE_REQUEST_CODE) {//打开本地文件管理器选择图片
  159. result = data == null ? null : data.getData();
  160. }
  161. Log.w(TAG,"{onActivityResultAboveL}文件路径地址:"+result.toString());
  162. myWebView.getMyBridgeWebChromeClient().getmUploadCallbackAboveL().onReceiveValue(new Uri[]{result});//将文件路径返回去,填充到input中
  163. myWebView.getMyBridgeWebChromeClient().setmUploadCallbackAboveL(null);
  164. return;
  165. }
  166.  
  167. }

混淆配置

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

  1. # Add project specific ProGuard rules here.
  2. # You can control the set of applied configuration files using the
  3. # proguardFiles setting in build.gradle.
  4. #
  5. # For more details, see
  6. # http://developer.android.com/guide/developing/tools/proguard.html
  7.  
  8. # If your project uses WebView with JS, uncomment the following
  9. # and specify the fully qualified class name to the JavaScript interface
  10. # class:
  11. #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
  12. # public *;
  13. #}
  14.  
  15. # Uncomment this to preserve the line number information for
  16. # debugging stack traces.
  17. #-keepattributes SourceFile,LineNumberTable
  18.  
  19. # If you keep the line number information, uncomment this to
  20. # hide the original source file name.
  21. #-renamesourcefileattribute SourceFile
  22.  
  23. #====WebView + js====
  24. -keepclassmembers class com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebView {
  25. public *;
  26. }
  27. -keepclassmembers class com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebChromeClient {
  28. public *;
  29. }
  30. -keepclassmembers class com.why.project.mybridgewebviewdemo.customwebview.jsbridgewebview.MyBridgeWebViewClient {
  31. public *;
  32. }
  33. # keep 使用 webview 的类
  34. -keepclassmembers class com.why.project.mybridgewebviewdemo.MainActivity {
  35. public *;
  36. }
  37. -keepattributes *Annotation*
  38. #解决:android sdk api >= 17 时需要加@JavascriptInterface”所出现的问题。
  39. -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. 提高测试脚本复用性降低DOM结构引起路径变化的影响

    问题描述 在定位元素时直接复制的xpath. 但是因为下面这些原因导致之前引用的路径失效, 不得不频繁修改脚本重新定位元素, 大降低了脚本的复用性, 也增加了维护的成本: 1. UI修改 (比如增加了 ...

  2. MAC使用小技巧之用好mac电脑?的10个必知的小技巧!

    很多朋友是不是都有这样的困惑,刚接手Mac电脑,无论是笔记本亦或是台式机,很是不方便,因为windows系统那种习惯已经先入为主了,今天就给大家普及一些小技巧. 当你看到这篇文章,不管你有没有mac电 ...

  3. plugin.go 源码阅读

    , nil)             }             if c.client != nil {                 c.client.Close()             } ...

  4. 获得指定数据库中指定块表中所有实体的id

    该函数也使用外部指定图纸中的数据库中的块 Int getIdsByDwgBlkName(AcDbDatabase *pDwg, CString strBlkName, AcDbObjectIdArra ...

  5. laravel 分页和共多少条 加参数的分页链接

    <div class="pagers "> <span class="fs pager">共 {{$trades->total() ...

  6. 遍历数组 foreach

    package com.java.array; public class Myforeach { public static void main(String[] ARGS){ /* int arr[ ...

  7. Django_cookie_session

    登录时候后台打印request.COOKIE 1.login页面正确登录的话,后台页面可以获取到浏览器携带的cookie的. 2.第一行的sessionid其实就是cookie值 3.session的 ...

  8. sum() 函数性能堪忧,列表降维有何良方?

    本文原创并首发于公众号[Python猫],未经授权,请勿转载. 原文地址:https://mp.weixin.qq.com/s/mK1nav2vKykZaKw_TY-rtw Python 的内置函数 ...

  9. MIP技术进展月报第3期:MIP小姐姐听说,你想改改MIP官网?

    一. 官网文档全部开源 MIP 是一项永久的开源的项目,提供持续优化的解决方案,当然官网也不能例外.从现在开始,任何人都可以在 MIP 官网贡献文档啦! GitHub 上,我们已经上传了 <官网 ...

  10. Android进阶加密-第1章-Android系统架构-读书笔记

    第 1 章 Android 系统架构 1.1 Android 系统架构 Android 系统架构分为五层,从上到下依次是应用层.应用框架层.系统运行库层.硬件抽象层和 Linux 内核层. 应用层(S ...