1

There is a way to call javascript function from webview and then let it call a method in Java to return the result. Like described in How to get return value from javascript in webview of android?

Now, the javascript function can fail (say due to a typo in javascript file). In that case, I would like to carry out some failover code in Java. What is a good way to do that?

My current code looks like this:

In Java:

    private boolean eventHandled = false;
    @Override
    public void onEvent() {
        eventHandled = false;
        webview.loadUrl("javascript:handleEvent()");

        // Wait for JS to handle the event.
        try {
            Thread.sleep(500);  // milliseconds
        } catch (InterruptedException e) {
            // log
        }   

        if (!eventHandled) {
            // run failover code here.
        }   
    }   
    public final MyActivity activity = this;
    public class EventManager {
        // This annotation is required in Jelly Bean and later:
        @JavascriptInterface
        public void setEventHandled() {
            eventHandled = true;
        }   
    };  

webview.addJavascriptInterface(new EventManager(), "eventManager");

In javascript:

function handleEvent() {
    var success =  doSomething();
    if (success) {
        eventManager.setEventHandled();
    }   
}

This seems to work fine for my case. Is there a better way than this "sleep for sometime and hope Javascript call is finished by then" method?

Community
  • 1
  • 1
tarkeshwar
  • 4,105
  • 4
  • 29
  • 35

1 Answers1

5

You can use a synchronization object for notifying and waiting:

public class EventManager {
    private final ConditionVariable eventHandled = new ConditionVariable();     

    public void setEventHandled() {
        eventHandled.open();
    }

    void waitForEvent() {
        eventHandled.block();
    }
}

private final EventManager eventManager = new EventManager();

@Override
public void onEvent() {
    webview.loadUrl("javascript:handleEvent()");

    // Wait for JS to handle the event.
    eventManager.waitForEvent();  
}       
Michael
  • 53,859
  • 22
  • 133
  • 139
  • If the javascript function fails and setEventHandled() does not get called, I want to run some failover code (as shown in question). This answe will just block waiting for the javascript call to succeed, no? – tarkeshwar Jun 01 '11 at 19:03
  • 1
    Use `block` method with timeout. – Michael Jun 01 '11 at 19:07