WebviewJavascriptBridge的使用與介紹

上一篇簡單介紹了Androi與前端H5 js的交互方式,那些方式對於一些簡單的交互足夠了,但是如果涉及到複雜的交互就很乏力,下面就來介紹一個Github上用來處理Android與js較複雜的交互的框架。
框架地址:
https://github.com/jesse01/WebViewJavascriptBridge

步驟:

  • 下載代碼,找到WebViewJavascriptBridge文件夾,注意這個文件夾下有清單文件,層級不要弄錯。
  • 在已有的工程中將這個項目以module的形式導入到AS中(框架使用ES編寫的),如圖
    這裏寫圖片描述

項目結構:

這裏寫圖片描述

  • 首先看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 = 0; 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(1, value.length() - 1)
                                            .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)
      })

      這裏寫圖片描述

      這種方式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)
              })

      效果圖

      這裏寫圖片描述
      這種方式是專門的在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)
              })
          }

      效果圖

      這裏寫圖片描述

      和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)
                  })
              }

      效果圖

      這裏寫圖片描述

這種方式是在java中註冊了action,在js中調用action。對於複雜的情況比較合適。

對於這個框架就簡單的介紹到這,下一篇將會對這一框架進行封裝,達到在html中直接引用一個js文件就實現專門的action。

代碼下載: http://download.csdn.net/detail/qq_27942511/9832140

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章