android jockeyjs库对webview的封装

来源:互联网 发布:魅蓝note6电信网络 编辑:程序博客网 时间:2024/05/29 16:50

jockeyjs库对h5和native代码交互做了优美的封装。

你可以写出像下面这种风格的代码,本文对它的实现做一个分析。

//Listen for an event from JavaScript and log a message when we have receied it.jockey.on("event-name", new JockeyHandler() {    @Override    protected void doPerform(Map<Object, Object> payload) {        Log.d("jockey", "Things are happening");    }});

项目地址:https://github.com/tcoulter/jockeyjs


jockey的实现类是JockeyImpl.java
@Override
public void on(String type, String data, JockeyHandler... handler) {
  if (!this.handles(type)) {
     CompositeJockeyHandler compositeJockeyHandler = new CompositeJockeyHandler();
     compositeJockeyHandler.setData(data);
     _listeners.put(type, compositeJockeyHandler);
  }

   _listeners.get(type).add(handler);  //从这里可以看到jockey对event进行了批处理
}       

因此我们搜索_listeners,ctrl f搜索下这个变量在类中的用处,跟踪到下面这个函数。
protected void triggerEventFromWebView(final WebView webView,
     JockeyWebViewPayload envelope) {
  final int messageId = envelope.id;
  String type = envelope.type;

   if (this.handles(type)) {
     final JockeyHandler handler = _listeners.get(type);                                       //取到handler
     handler.perform(envelope.payload, new OnCompletedListener() {
        @Override
        public void onCompleted() {
           // This has to be done with a handler because a webview load
           // must be triggered
           // in the UI thread
           _handler.post(new Runnable() {
              @Override
              public void run() {
                  triggerCallbackOnWebView(webView, messageId, handler.getData());
              }
           });
        }
     });
  }
}

可以想象到程序必定在某个地方(某个类)监听到我们想要的event,然后triggerEventFromWebView。
启动工程中ctrl f搜索大法搜索 triggerEventFromWebView。


因此我们找到了这个类-->JockeyWebViewClient.java
public voidprocessUri(WebView view, URI uri)
     throws HostValidationException {
  String[] parts = uri.getPath().replaceAll("^\\/", "").split("/");
  String host = uri.getHost();
   JockeyWebViewPayload payload = checkPayload(_gson.fromJson(
        uri.getQuery(), JockeyWebViewPayload.class));
   if (parts.length > 0) {
     if (host.equals("event")) {
        getImplementation().triggerEventFromWebView(view, payload);
     } else if (host.equals("callback")) {
        getImplementation().triggerCallbackForMessage(
              Integer.parseInt(parts[0]));
     }
  }
}
然后再搜索processUri,我们看到
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
  if (delegate() != null
        && delegate().shouldOverrideUrlLoading(view, url))
     return true;
   try {
     URI uri = new URI(url);
      if (isJockeyScheme(uri)) {     //因此jockey封装event的方式很简单,就是再js那边加一个jocky的头部 如果是jocky的头部
                                                  //就捕捉相应的事件进行处理
       processUri(view, uri);
        return true;
     }
  } catch (URISyntaxException e) {
     e.printStackTrace();
  } catch (HostValidationException e) {
     e.printStackTrace();
     Log.e("Jockey", "The source of the event could not be validated!");
  }
  return false;
}

总结一下,jocky对于监听webview的事件的实现其实很简单,就是在shouldOverrideUrlLoading的地方增加一个jocky头部。







1 0