Issue
I wanted to toast a return string from a JavaScript function in my android app, I've been searching and tried some codes for days now but seems that I got no luck to find a correct one.
Here is the JS function that I want to be called in android to return a string value
function myFunction()
{
var str= document.getElementsByName('txt')[0].value;
window.android.myFunction(str);
}
MainActivity.java
//create interface
JsInterface jsInterface = new JsInterface();
wv.setWebViewClient(new WebViewClient());
wv.setWebChromeClient(new WebChromeClient());
wv.getSettings().setJavaScriptEnabled(true);
//add interface
wv.addJavascriptInterface(jsInterface, "android");//android is the keyword that will be exposed in js
//load file
wv.loadUrl("file:///android_asset/test.html");
Toast.makeText(getApplicationContext(), myFunction(), Toast.LENGTH_LONG);
}
//javascript interface
private class JsInterface{
public String myFunction(String msg){
return msg;
}
}
I'm a newbie to this kind of platform and also in Javascript. I appreciate those who'll answer. thanks.
Solution
I think you need to change in your code the following:
Run your JavaScript function from
WebViewClient.onPageFinished
to make sure that the document has actually loaded, and in order to run it, useloadUrl()
function with ajavascript:
URL:wv.setWebViewClient(new WebViewClient() { @Override void onPageFinished(WebView view, String url) { view.loadUrl("javascript:myFunction();void(0);"); } }
Annotate the Java method you want to expose with
@JavascriptInterface
annotation (and make itvoid
, as you don't actually want to return anything back to JavaScript), and callToast.makeText()
from inside it, but make sure you switch to the UI thread, because injected Java methods run on a dedicated background thread:private class JsInterface { private Context mContext; JsInterface(Context context) { mContext = context; } @JavascriptInterface public void myFunction(String msg) { new Handler(Looper.getMainLooper()).post(new Runnable() { @Override public void run() { Toast.makeText(mContext, msg, Toast.LENGTH_LONG); } }); } }
And just pass the application context to
JsInterface
upon creation:JsInterface jsInterface = new JsInterface(getApplicationContext());
Also note that you have two functions named myFunction
in your JavaScript: the one in the injected object, available via android.myFunction()
, and the one you have defined yourself, it is available as just myFunction()
or window.myFunction()
. It is actually better to use different names for them to avoid confusion.
Answered By - Mikhail Naganov
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.