Ingo Bürk
Ingo Bürk

Reputation: 20033

Passing callback from JavaScript to Java (Android)

I'm developing an app for Android using HTML5/JavaScript. Running into limitations, I want to call a function that is realized in the Java code from within JavaScript. To be more precise, I want to create a certain type of dialog. This is fairly easy (I will only give a rough outline/stub):

public class MyClass () {
    // other stuff

    public void createMyDialog (/* arguments */) {
        DialogBuilder builder = ...
        builder.setItems(myItems, new DialogInterface.OnClickListener () {
            @Override
            public void OnClick (DialogInterface dialog, int which) {
                droidGap.loadUrl(/* what now? */);
            }
        });
    }
}

Then this class is revealed to JavaScript with

MyClass myClass = new MyClass();
appView.addJavascriptInterface(myClass, "myClass");

So far so good. I can now access window.myClass.createMyDialog() from within JavaScript. However, what I'd like to do is pass a callback that will be called with the which variable as a parameter. This means having a signature like

public void createMyDialog (final String callback)

and calling it with something like

window.myClass.createMyDialog(
    function (which) {
        alert(which);
    }
);

I can get this to work my passing the function as a string (using String() around the function) and calling appView.loadUrl("javascript:(" + callback + ")(" + which + ");"); from Java. Never mind that this solution doesn't feel very clean, it has a big disadvantage – to finally come to the point. Because in JavaScript, I'm actually calling createMyDialog from within a class and I'd like to do somehting like this:

function myJSClass () {
    this.myVar = -1;

    this.myFunc = function () {
        window.myClass.createMyDialog(
            function (which) {
                this.myVar = which;
            }
        );
    }
}

var myObj = new myJSClass();
myObj.myFunc();

The problem now being that with the solution from above, this will refer to window rather than the class instance. This isn't a new problem, but none of the typical solutions (storing var _this = this outside the call and using _this.myVar = which or using bind) work as the context of this is just completely lost because the function will be called from Java.

I know that it has to be possible since the PhoneGap framework offers navigator.notification.confirm which pretty much does exactly what I want. What is the way to go here?

Thanks in advance!

Upvotes: 1

Views: 1955

Answers (1)

Simon MacDonald
Simon MacDonald

Reputation: 23273

First, you should really write a Plugin. We've already run into a number of Java/JS and JS/Java problems so you should take advantage of our tested code.

Second, you are going to need to run your dialog on the UI thread. If you don't there will be problems.

Third, if you want to call as specific success/error call back from Java when a dialog action has happened you can do that via the PluginResult class. If you set the success condition the success callback will be invoked and vice versa.

Check out the PG code for notification which contains examples on a number of dialogs:

https://git-wip-us.apache.org/repos/asf?p=cordova-android.git;a=blob;f=framework/src/org/apache/cordova/Notification.java;h=958ab26b842b41326523b9fa154aa8c71885c8ab;hb=HEAD

Upvotes: 1

Related Questions