天天看点

WebviewJavascriptBridge的使用与介绍

上一篇简单介绍了Androi与前端H5 js的交互方式,那些方式对于一些简单的交互足够了,但是如果涉及到复杂的交互就很乏力,下面就来介绍一个Github上用来处理Android与js较复杂的交互的框架。

框架地址:

https://github.com/jesse01/WebViewJavascriptBridge

步骤:

  • 下载代码,找到WebViewJavascriptBridge文件夹,注意这个文件夹下有清单文件,层级不要弄错。
  • 在已有的工程中将这个项目以module的形式导入到AS中(框架使用ES编写的),如图
    WebviewJavascriptBridge的使用与介绍

项目结构:

WebviewJavascriptBridge的使用与介绍
  • 首先看assets文件夹下的html文件和txt文件,txt文件全是js代码,主要用来搭建与java交互的桥梁,不需要管,后面会提到。html文件中包含于java交互的代码。
  • WVJBWebViewClient也是用来搭建桥梁的不需要细看。只需要看一下onPageFinished方法,这里会加载上面的txt文件,在java中执行txt中的js代码,构建桥梁
    @Override
        public void onPageFinished(WebView view, String url) {
            try {
                InputStream is = webView.getContext().getAssets()
                        .open("WebViewJavascriptBridge.js.txt");
                int size = is.available();
                byte[] buffer = new byte[size];
                is.read(buffer);
                is.close();
                String js = new String(buffer);
                executeJavascript(js);
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            if (startupMessageQueue != null) {
                for (int i = ; i < startupMessageQueue.size(); i++) {
                    dispatchMessage(startupMessageQueue.get(i));
                }
                startupMessageQueue = null;
            }
            super.onPageFinished(view, url);
        }
    
        public void executeJavascript(String script) {
            executeJavascript(script, null);
        }
    
        public void executeJavascript(String script,
                    final JavascriptCallback callback) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                    webView.evaluateJavascript(script, new ValueCallback<String>() {
                        @Override
                        public void onReceiveValue(String value) {
                            if (callback != null) {
                                if (value != null && value.startsWith("\"")
                                        && value.endsWith("\"")) {
                                    value = value.substring(, value.length() - )
                                            .replaceAll("\\\\", "");
                                }
                                callback.onReceiveValue(value);
                            }
                        }
                    });
                } else {
                    if (callback != null) {
                        myInterface.addCallback(++uniqueId + "", callback);
                        webView.loadUrl("javascript:window." + kInterface
                                + ".onResultForScript(" + uniqueId + "," + script + ")");
                    } else {
                        webView.loadUrl("javascript:" + script);
                    }
                }
            }
               
    上面会根据不通过的Android系统版本使用不同的方法来执行这些js代码。

交互

这里为了看起来清楚,把英文提示改成了汉字

  • JAVA→JS
    • 第一种方式:

      JAVA代码

      findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
      
        @Override
             public void onClick(View v) {
                 webViewClient.send("来自java的数据", new WVJBWebViewClient.WVJBResponseCallback() {
      
                     @Override
                     public void callback(Object data) {
                         Toast.makeText(MainActivity.this, "js接收到数据并返回数据:  " + data, Toast.LENGTH_LONG).show();
                     }
                 });
             }
         });
                 
      JS代码
      bridge.init(function(message, responseCallback) {
       log('JS收到数据', message)
          var data = { 'js接收到消息了':'啦啦!' }
          log('JS返回数据', data)
          responseCallback(data)
      })
                 
      WebviewJavascriptBridge的使用与介绍
      这种方式java传过来的参数都会统一调用bridge.init()中设置的回调方法的方法。可以在这里对message进行判断类型,执行不同的操作。
    • 第二种方式:

      JAVA代码

      findViewById(R.id.button2).setOnClickListener(new OnClickListener() {
      
              @Override
              public void onClick(View v) {
                  try {
                      webViewClient.callHandler("javaCallJs", new JSONObject("{\"java的问候\": \"你好, JS!\" }"), new WVJBWebViewClient.WVJBResponseCallback() {
      
                          @Override
                          public void callback(Object data) {
                              Toast.makeText(MainActivity.this, "来自js的回应:" + data, Toast.LENGTH_LONG).show();
                          }
                      });
                  } catch (JSONException e) {
                      e.printStackTrace();
                  }
              }
          });
                 
      JS代码
      bridge.registerHandler('javaCallJs', function(data, responseCallback) {
                  log('java调用action javaCallJs', data)
                  var responseData = { 'js收到':'哇呜' }
                  log('JS的响应', responseData)
                  responseCallback(responseData)
              })
                 
      效果图
      WebviewJavascriptBridge的使用与介绍
      这种方式是专门的在js中注册一个action,在java中callHandler方法,传入action,调用专门的js方法。对于比较复杂交互来说代码还是比较清楚明了的。
  • JS→JAVA
    • 第一种方式:

      JAVA代码

      super(webView,  new WVJBWebViewClient.WVJBHandler() {
      
                      @Override
                      public void request(Object data, WVJBResponseCallback callback) {
                          Toast.makeText(MainActivity.this, "接到js的数据:  " + data, Toast.LENGTH_LONG).show();
                          callback.callback("收到了你的问候,Js");
                      }
                  });
                 
      JS代码
      var button = document.getElementById('buttons').appendChild(document.createElement('button'))
          button.innerHTML = '调用java并传数据'
          button.onclick = function(e) {
              e.preventDefault()
              var data = '你好啊, Java'
              log('JS发送消息给java', data)
              bridge.send(data, function(responseData) {
                  log('来自java的回应', responseData)
              })
          }
                 
      效果图
      WebviewJavascriptBridge的使用与介绍
      和java调用js第一种方式一样,这个会统一调用,通过message的类型进行判断进行不同的操作
    • 第二种方式:

      JAVA代码

      registerHandler("jsCallJava", new WVJBWebViewClient.WVJBHandler() {
      
                      @Override
                      public void request(Object data, WVJBResponseCallback callback) {
                          Toast.makeText(MainActivity.this, "收到Js的数据  " + data, Toast.LENGTH_LONG).show();
                          callback.callback("收到你问候,谢谢!)");
                      }
                  });
                 
      JS代码
      var callbackButton = document.getElementById('buttons').appendChild(document.createElement('button'))
              callbackButton.innerHTML = '调用java注册的action并传数据'
              callbackButton.onclick = function(e) {
                  e.preventDefault()
                  log('JS调用java action "jsCallJava"')
                  bridge.callHandler('jsCallJava', {'Js的问候': '你好,java!'}, function(response) {
                      log('JS收到java的响应', response)
                  })
              }
                 
      效果图
      WebviewJavascriptBridge的使用与介绍

这种方式是在java中注册了action,在js中调用action。对于复杂的情况比较合适。

对于这个框架就简单的介绍到这,下一篇将会对这一框架进行封装,达到在html中直接引用一个js文件就实现专门的action。

代码下载: http://download.csdn.net/detail/qq_27942511/9832140

继续阅读