Android Open Source - JSBridge J S Bridge






From Project

Back to project page JSBridge.

License

The source code is released under:

MIT License

If you think the Android project JSBridge listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.siva4u.jsbridge;
/* w  ww.  j a  v  a2  s. com*/
import java.io.IOException;
import java.io.InputStream;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.webkit.WebViewClient;

@SuppressLint({ "NewApi", "SetJavaScriptEnabled", "JavascriptInterface" })
public class JSBridge {
  
  private Context        context      = null;
  private WebView        webView      = null;
  private JSBridgeInteface  jsListener    = null;
  private JSBridgeHandler    jsBridgeHandler  = null;
  
  private int      uniqueId      = 0;
  private JSONArray  startupMessageQueue  = new JSONArray();
  private JSONObject  responseCallbacks  = new JSONObject();
  private JSONObject  messageHandlers    = new JSONObject();

  public static final String JS_BRIDGE_FILE_NAME      = "JSBridge.min.js";
  public static final String JS_BRIDGE          = "JSBridge";
  public static final String JS_BRIDGE_SEND_NATIVE_QUEUE  = "_handleMessageFromNative";

  public static void Log(String str) {
    System.out.println("JSBridge: Log: "+str);
  }
  public static String getString(JSONObject obj, String forKey) {
       try {
         if(forKey != null) return obj.get(forKey).toString();
         else {
           return obj.toString();
         }
    } catch (JSONException e) {
      e.printStackTrace();
    }
      return null;
    }
  public static String getString(JSONObject obj) {
      return getString(obj, null);
    }
  public static JSONObject getJSONObject(String str) {
      try {
      return new JSONObject(str);
    } catch (JSONException e) {
      e.printStackTrace();
    }
      try {
      return new JSONObject("{'data':"+str+"}");
    } catch (JSONException e) {
      e.printStackTrace();
    }
      return new JSONObject();
    }
  public static JSONObject updateJsonObject(JSONObject obj, String key, String value) {
    try {
      if((obj != null) && (key != null) && (value != null)) {
        return obj.put(key,value);
      }
    } catch (JSONException e) {
      e.printStackTrace();
    }
    return obj;
  }
  public static JSONObject updateJsonObject(JSONObject obj, String key, JSONObject value) {
    try {
      if((obj != null) && (key != null) && (value != null)) {
        return obj.put(key,value);
      }
    } catch (JSONException e) {
      e.printStackTrace();
    }
    return obj;
  }
  public static JSONObject updateJsonObject(JSONObject obj, String key, Object value) {
    try {
      if((obj != null) && (key != null) && (value != null)) {
        return obj.put(key,value);
      }
    } catch (JSONException e) {
      e.printStackTrace();
    }
    return obj;
  }
  
  private final String getAssetFileContents(String fileName) {
        String contents = "";
        try {
            InputStream stream = context.getAssets().open(fileName);
            byte[] buffer = new byte[stream.available()];
            stream.read(buffer);
            stream.close();
            contents = new String(buffer);
        } catch (IOException e) {}
        return contents;
  }
  
  private class JSBridgeWebViewClient extends WebViewClient {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
      if(jsListener != null) {
        jsListener.shouldOverrideUrlLoading(view, url);
      }
      return false;
    }
    @Override
    public void onPageStarted (WebView view, String url, Bitmap favicon) {
      if(jsListener != null) {
        jsListener.onPageStarted(view, url, favicon);
      }
    }
    @Override
    public void onPageFinished(WebView view, String url) {      
      if(startupMessageQueue != null) {
        int queueCount = startupMessageQueue.length();
        if(queueCount > 0) {
          for (int i = 0; i < queueCount; i++) {
            try {
              dispatchMessage(startupMessageQueue.getString(i));
            } catch (JSONException e) {
              e.printStackTrace();
            }
          }
        }        
            startupMessageQueue = null;
      }
      if(jsListener != null) {
        jsListener.onPageFinished(view,url);
      }
    }
  }

  private class AndroidAPI extends JSBridgeAPIBase {
    public AndroidAPI(Context c, WebView view) {
      super(c, view);
    }

    @JavascriptInterface
    public void NativeAPI(String msgQueue) {
      try {
        JSONArray messages = new JSONArray(msgQueue);
        if(messages != null) {
          int msgCount = messages.length();
          if(msgCount > 0) {
            for (int i = 0; i < msgCount; i++) {
              JSONObject message = messages.getJSONObject(i);
              if(message != null) {
                JSBridgeCallback responseCallback = null;
                String responseId = getString(message,"responseId");
                if(responseId != null) {
                  responseCallback = (JSBridgeCallback) responseCallbacks.get(responseId);
                  if(responseCallback != null) {
                    try {
                      String data = getString(message,"responseData");
                      responseCallback.callBack(((data != null)?(getJSONObject(data)):(null)));
                      responseCallbacks.remove(responseId);
                    } catch(Exception e) {
                      e.printStackTrace();
                    }
                  }
                } else {
                  final String callbackId = getString(message,"callbackId");
                  class responseCallBackImpl implements JSBridgeCallback {
                    @Override
                    public void callBack(JSONObject data) {
                      if(callbackId != null) {
                        JSONObject msg = new JSONObject();
                        updateJsonObject(msg, "responseId", callbackId);
                        updateJsonObject(msg, "responseData", data);
                        queueMessage(msg);
                      }
                    }
                  }
                  
                  // if callbackId is null then empty callback will be created.
                  responseCallback = new responseCallBackImpl();
                  
                  JSBridgeHandler hander = null;
                  String eventName = getString(message,"eventName");
                  if(eventName != null) {
                    hander = (JSBridgeHandler) messageHandlers.get(eventName);
                  }                  
                  if(hander != null) {
                    hander.hanlder(message.getJSONObject("data"), responseCallback);
                  } else {
                    if(jsBridgeHandler != null) {
                      JSONObject data = new JSONObject();
                      Object obj = message.opt("data");
                      if(obj != null) {
                        data.put("data", obj);
                      }
                      jsBridgeHandler.hanlder(data,responseCallback);
                    }
                  }
                }
              }
            }
          }
        }
      } catch (JSONException e) {
        e.printStackTrace();
      }      
    }
    @JavascriptInterface
    public void Log(String str) {
      JSBridge.Log(str);
    }
    @JavascriptInterface
    public void LogArray(String str) {
      JSONObject obj;
      try {
        obj = new JSONObject(str);
        JSBridge.Log("LogArray: "+obj);
      } catch (JSONException e) {
        JSBridge.Log("LogArray: EXCEPTION");
        e.printStackTrace();
      }
    }    
  }
  
    private void dispatchMessage(final String jsonStr) {
    webView.post(new Runnable() {
        @Override
        public void run() {
          webView.loadUrl("javascript: "+JS_BRIDGE+"."+JS_BRIDGE_SEND_NATIVE_QUEUE+"('"+jsonStr+"');");
        }
    });
    }

    private void queueMessage(JSONObject jsonObj) {
      if(startupMessageQueue != null) {
        startupMessageQueue.put(jsonObj);
      } else {
        dispatchMessage(getString(jsonObj));
      }
    }
    
  public JSBridge(Object jsListener, Context context, WebView webview) {
    this.context = context;
    this.webView = webview;
    if(JSBridgeInteface.class.isInstance(jsListener)) {
      this.jsListener = (JSBridgeInteface)jsListener;
    }
    if(JSBridgeHandler.class.isInstance(jsListener)) {
      this.jsBridgeHandler = (JSBridgeHandler)jsListener;
    }
    if(webView != null) {
      registerJavaScriptAPI(new AndroidAPI(context, webview));
      webView.getSettings().setJavaScriptEnabled(true);
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        WebView.setWebContentsDebuggingEnabled(true);
      }
      webView.setWebViewClient(new JSBridgeWebViewClient());
      webView.loadUrl("javascript: "+getAssetFileContents(JS_BRIDGE_FILE_NAME));
    }
  }
  
  public void registerJavaScriptAPI(JSBridgeAPIBase instance) {
    if(webView != null) {
      webView.addJavascriptInterface(instance, instance.getClass().getSimpleName());
    }
  }

  public void loadHTML(String url) {
    if(webView != null) {
      webView.loadUrl(url);
    }
  }
    
  public void send(String eventName, JSONObject data, JSBridgeCallback responseCallback) {
      JSONObject message = new JSONObject();
      updateJsonObject(message,"data",data);
      updateJsonObject(message,"eventName",eventName);
      if(responseCallback != null) {
          String callbackId = "android_cb_"+(++uniqueId);
          updateJsonObject(responseCallbacks,callbackId,responseCallback);
           updateJsonObject(message,"callbackId",callbackId);
      }      
      queueMessage(message);
  }
  
  public void registerEvent(String eventName, JSBridgeHandler hanlder) {
    try {
      messageHandlers.put(eventName, hanlder);
    } catch (JSONException e) {
      e.printStackTrace();
    }
  }
  
  public void deRegisterEvent(String eventName, JSBridgeHandler hanlder) {
    messageHandlers.remove(eventName);
  }
}




Java Source Code List

com.siva4u.jsbridge.JSBridgeAPIBase.java
com.siva4u.jsbridge.JSBridgeCallback.java
com.siva4u.jsbridge.JSBridgeHandler.java
com.siva4u.jsbridge.JSBridgeInteface.java
com.siva4u.jsbridge.JSBridge.java
com.siva4u.jsbridge.example.TestAPIOne.java
com.siva4u.main.MainActivity.java