Saturday, December 3, 2011

How javascript call java in Phonegap android


Phonegap is a great mobile solution, since I am working in Grapple mobile now, our platform use quite similar solution with Phonegap, so I really want to learn Phonegap to see if we can steal some ideas from it.
What troubled me a long time is in its android platform: I wonder how does its javascript code calls java native code? Before I tried to read its android source code, but did not find the answer. This week I spent some time on its source code, finally I find the answer. I would like to share this result with you, this might be valuable especially if you want to dig more to phonegap, since I seldom find the answer from google or books about phonegaps, none of them talks about this.

The phonegap source code I checked out is from github, the current version is 1.2:
1. phonegap android source code: https://github.com/callback/callback-android
2. phonegap platform sample code: https://github.com/callback/phonegap

Digging the source code
From phonegap-1.2.0.js

For example looking at accelerometer:  in javascript layer, the accelerometer is implemented by calling Phonegap.exec() method:
The PhoneGap.exec() method will be like this: So the exec method will invoke a javascript prompt()- which is popping up an dialog, huh, it sounds weird.

Let's look at the java code:
Inside com.phonegap.DroidGap.java, find the inner class GapClient, which is a subclass of WebChromeClient, it override the following 3 methods: onJsAlert(), onJsConfirm() and onJsPrompt()
Here we only look at the onJsPrompt(), look at the android API for onJsPrompt():
Tell the client to display a prompt dialog to the user. If the client returns true, WebView will assume that the client will handle the prompt dialog and call the appropriate JsPromptResult method. If the client returns false, a default value of false will be returned to to javascript. The default behavior is to return false.

So it is quite clear that: if prompt() is called in javascript layer, then onJsPrompt() method will get invoked in java layer. Phonegap just uses this way to handle the javascript to java communication.

Let's look at the onJsPrompt() method in details:  So here the phoneGap PluginManager will delegate the the javascript call to different native plugins.

From the article of http://stackoverflow.com/questions/7251557/phonegap-and-prompt
and phonegap release note: http://phonegap.com/2011/04/28/phonegap-0-9-5-released/, it mentioned that
Worked around JavaScript bridge exception for Android 2.3. Use “prompt” instead of calling objects directly.
So it seems that this is a workaround for an issue in Android 2.3.

Summary
To recap, this is the flow of javascript call java in phonegap android is like this:
1. in javascript layer, all the javascript method will finally delegate to Phonegap.exec() method
2. PhoneGap.exec() will call prompt()
3. In java layer, DriodGap.GapClient override onJsPrompt(), which will capture the prompt() method call in java, which then delegate to PluginManager to invoke the native java method call.


4 comments:

  1. There is a post from PhoneGap that helps to solve similar problem as yours. Please take a look at http://phonegap.com/2011/05/18/debugging-phonegap-javascript/

    ReplyDelete
  2. Hi, Ayshwariya,
    Thanks for your interest. I think all you need is just click the "Join this site" button,
    or usually I use google reader, you can add my blog url in your google reader list.

    ReplyDelete
  3. Very nice post!!! Thank You for Sharing.

    ReplyDelete
  4. The SBOK guide of http://www.scrumstudy.com will give you a clear understanding of how to run effective daily standup meetings. It also provides you detailed information on Agile Project Management methodologies such as planning/review/retrospective meeting, and how to take advantages of related tools and so on.

    ReplyDelete