In previous blog How is OData request routed to Offline data store by OData offline plugin , according to comment, the Offline store will only be available once it is opened successfully. The open operation is done in Device native API, delegated in line 232.

/wp-content/uploads/2016/08/clipboard1_1008819.png

The exec is available in exported module returned by require(‘cordova/exec’):

/wp-content/uploads/2016/08/clipboard2_1008820.png

And now I would like to understand how this exec is delegated to Java Native API in Android platform.

In folder android I have found this cordova.js:

/wp-content/uploads/2016/08/clipboard3_1008830.png

The exec call is implemented by module defined in cordova.js:

/wp-content/uploads/2016/08/clipboard4_1008831.png

Here means the exec is implemented by androidExec:

/wp-content/uploads/2016/08/clipboard5_1008832.png

Key logic of androidExec implementation

/wp-content/uploads/2016/08/clipboard6_1008836.png

1. meaning of parameters success, fail, service, action, args

  • success & fail: JavaScript callback function after the specified Java API is called
  • service: Java class name
  • action: Java class method name
  • args: arguments passed from JavaScript to Java

2. There are two technical approaches for communication from JavaScript to Java in Android platform, see them in constant jsToNativeModes:

/wp-content/uploads/2016/08/clipboard7_1008838.png

Example of JS_OBJECT, or called JavaScript interface:

Java code:


import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
public class WebViewGUI extends Activity {
  WebView mWebView;
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mWebView = new WebView(this);
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.addJavascriptInterface(new JavaScriptInterface(), "jsinterface");
    mWebView.loadUrl("file:///android_asset/www/index.html");
    setContentView(mWebView);
  }
  final class JavaScriptInterface {
    JavaScriptInterface () { }
    public String getSomeString() {
      return "string";
    }
  }
}

In JavaScript code, consume Java method getSomeString as below:


<script>
var String = window.jsinterface.getSomeString();
</script>

Back to implementation of AndroidExec:


var msgs = nativeApiProvider.get().exec(bridgeSecret, service, action, callbackId, argsJson);

it will again delegate the call to exec method of instance returned by nativeApiProvider.get().

/wp-content/uploads/2016/08/clipboard8_1008839.png


Again look at implementation in nativeapiprovider.js, from the comment in line 21 we can know the currentApi returned by get comes from either ExposedJsApi.java or PromptBasedNativeAPI.

/wp-content/uploads/2016/08/clipboard9_1008840.png

The ExposedJsApi.java could be found from this location:

/wp-content/uploads/2016/08/clipboard10_1008841.png

It is a Java interface with method exec defined:

/wp-content/uploads/2016/08/clipboard11_1008842.png

The call from JavaScript to Java is done via prompt call:

/wp-content/uploads/2016/08/clipboard12_1008843.png

And the Java class SystemExposedJsApi implements the interface, delegates call to the instance of class CordovaBridge.

/wp-content/uploads/2016/08/clipboard13_1008845.png


CordovaBridge will delegate to PluginManager:

/wp-content/uploads/2016/08/clipboard14_1008846.png

Plugin manager first gets responsible plugin Java class by name, then perform the execute method of plugin.

/wp-content/uploads/2016/08/clipboard15_1008847.png

For example this is OData offline plugin service class, in its execute method we can find there are lots of IF-ELSE branch to implement different offline operation.

/wp-content/uploads/2016/08/clipboard16_1008851.png

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply