Reputation: 682
I have created an android WebView
, and injected javascript
interface using addJavascriptInterface(mObject, "jsinterface")
. It works fine until I create an object with same name (jsinterface) in JavaScript using the new
operator.
WebView mWebView = findViewById(R.id.myWebView);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebChromeClient(new MyWebChromeClient((Activity)mContext));
mWebView.addJavascriptInterface(new testClass(), "jsinterface");
mWebView.loadUrl("UrlToLoad");
public class testClass{
public testClass() {
}
@JavascriptInterface
public String testNativeMethod() {
return "Java method called!!";
}
}
function test(msg){
this.message = msg;
this.testJSMethod = function(){
return this.message;
}
}
alert(jsinterface.testNativeMethod()); // prints Java method called!!
jsinterface= new test("JS method called...");
alert(jsinterface.testJSMethod()); // prints JS method called...
alert(jsinterface.testNativeMethod()); // errors "NPMethod called on non- NPObject"
Is this possible for a javascript
object to have access to both , i.e javascript
methods and native JAVA
methods(exposed to it via javascriptinterface
) ? Is there any possibility of setting any property to webview
OR executing any JS script
to get this done?
Upvotes: 9
Views: 34084
Reputation: 2023
You may try to make another object, which will retranslate calls to javascript interface.Implement onPageStarted
method in WebViewClient
, and inject javascript in onPageStarted
method, in the following way.
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
@Override
public void onPageStarted (WebView view, String url, Bitmap favicon){
String jsScript= "javascript:var functions_array = ['testNativeMethod'];";
jsScript+="var jsinterface = {};"
jsScript+="functions_array.map(function(id){"
jsScript+="jsinterface[id]= function() {"
jsScript+="try{return temp_obj[id].apply(temp_obj, arguments);}"
jsScript+="catch(e) { console.log('ERROR: ' + e + ', method ' + id);"
jsScript+="return false;}}})"
view.loadUrl(jsScript);
}
});
Hope this helps :-)
Upvotes: 5
Reputation: 30985
Think about document
in javascript. When you are in a web browser, this is a global object that you have access to at any point. If you make your own new
var called document
, you are going to have problems accessing the global document
.
When you execute this line:
mWebView.addJavascriptInterface(new testClass(), "jsinterface");
you are adding a global object called jsinterface
. This is the same situation as document
. If you create a var with the same name, it will overwrite the existing global reference.
Once you add a javascript interface to the WebView
, you don't need to create a new
reference to the interface. addJavascriptInterface
has already done that for you.
Upvotes: 14