2

How to pass a function as a parameter in Javascript Interface, save it as a string and then call?

For example, I describe the Javascript Interface:

class JSInterface{
  String myFunction;

  //set function into myFunction attribute
  @JavascriptInterface
  public void setMyFunction(String func) {
    this.myFunction = func;
  }

  @JavascriptInterface
  public void executeMyFunction() {
    webView.loadUrl("javascript:"+this.myFunction);
  }

}

Add it:

//...

webview..addJavascriptInterface(new JSInterface, "application");

//...

In JS:

window.application.setMyFunction(function(){
        //some code here...
});

NOTE: Transfer function from JS need in this form, not as a string or json.

But in fact, in setMyFunction i get "undefined" but expect "window.application.setMyFunction(function(){ //some code here...});". Tell me please what to do, I will be very grateful!

Oleg_Korchickiy
  • 298
  • 5
  • 15

2 Answers2

0

try this one:

Convert Javascript Object (incl. functions) to String

then attach function call to the string:

function(){
..
}()

and call eval() on that string.

Community
  • 1
  • 1
Robert
  • 3,276
  • 1
  • 17
  • 26
  • Do not quite understand what you mean. The problem is that I can not do anything on the `Javascript side`. I can only handle parameters that are passed to `Javasctipt Intarface`. – Oleg_Korchickiy Oct 06 '13 at 20:07
  • What executes the javascript then? If this is handled on client side, the the function in string should be sufficient? – Robert Oct 06 '13 at 20:10
  • Yes, i need to set string like `"function(){ //some code here... }"` into `myFunction` attribute. It will be enough. But i get only `"undefined"`. – Oleg_Korchickiy Oct 06 '13 at 22:15
  • Yes, I read it, but, as I said, I can not do anything on the Javascript side, only on the Java side. – Oleg_Korchickiy Oct 07 '13 at 07:09
  • Something on client side needs to execute the statement I suppose, anyway if you want self invoking function, add '()' at the end. – Robert Oct 07 '13 at 07:37
0

To solve this problem, when function passed as null, we need to declare the function that will be send the js function into JS Interface as string.

We also need to do this when onPageFinished.

For example:

@Override
public void onPageFinished(WebView view, String url) {
    view.loadUrl("javascript: window.APPLICATION.setMyFunction = function(func){"
        + "window.APPLICATION.setMyFunctionAsString(func.toString());"
        + "};");
    super.onPageFinished(view, url);
}

...and setMyFunctionAsString in JS Interface:

@JavascriptInterface
public void setMyFunctionAsString(String func) {
    this.myFunction = func;
}

Now, finnaly, when we do:

window.APPLICATION.setMyFunction(function(){
        //some code here...
});

we will have "window.APPLICATION.setMyFunction(function(){\n//some code here...\n});" in myFunction and can easily call it like:

@JavascriptInterface
public void executeMyFunction() {
    webView.loadUrl("javascript:"+this.myFunction);
}

I hope that this will help someone =)

Oleg_Korchickiy
  • 298
  • 5
  • 15