How Does Evaluatejavascript Work

How does evaluateJavascript work?

There is an example of the evaluateJavascript method being used in this sample:

https://github.com/GoogleChrome/chromium-webview-samples/tree/master/jsinterface-example

Essentially if the javascript you execute in the WebView returns a value it'll be passed in the callback.

The main thing to note is that the String returned in OnReceiveValue is either a JSON Value, JSON Object or JSON Array depending on what you return.

Things to note about this is if you return a single value, you need to use setLenient(true) on a JSON reader for it to work.

     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
// In KitKat+ you should use the evaluateJavascript method
mWebView.evaluateJavascript(javascript, new ValueCallback<String>() {
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onReceiveValue(String s) {
JsonReader reader = new JsonReader(new StringReader(s));

// Must set lenient to parse single values
reader.setLenient(true);

try {
if(reader.peek() != JsonToken.NULL) {
if(reader.peek() == JsonToken.STRING) {
String msg = reader.nextString();
if(msg != null) {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
}
}
}
} catch (IOException e) {
Log.e("TAG", "MainActivity: IOException", e);
} finally {
try {
reader.close();
} catch (IOException e) {
// NOOP
}
}
}
});
}

The reason you may still want to use a parser for a string response is it is converted to a JSON value which means it will be wrapped in quotes.

For example if you went:

mWebView.evaluateJavascript("(function() { return 'this'; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints: "this"
}
});

It would print the string this, wrapped in double quotes: "this".

Other examples worth noting:

mWebView.evaluateJavascript("(function() { return null; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints the string 'null' NOT Java null
}
});

mWebView.evaluateJavascript("(function() { })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); //s is Java null
}
});

mWebView.evaluateJavascript("(function() { return ''; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints "" (Two double quotes)
}
});

Android Webview EvaluateJavascript sometimes does not return a response

I did eventually figure out what happened here.

The shorter version is, this can happen when you have a memory leak and an object that is utilizing a semi-destroyed webview will fire off commands, but the newly-initialized webview will not receive a response because it is going to a dead listener.

If you want to prevent this from occurring, just make sure that all objects that maintain an application Context are properly disposed of or correctly reset if the activity restarts, else you have all objects that use the same Application-level context, but are using new views and callbacks entirely.

Android webview blocking evaluateJavascript

Since the call onReceiveValue won't be synchronous and would involve blocking your main Thread in case you want to make it synchronous, I would recommend you to avoid doing it. Instead of trying to implement it as synchronous call, implement callbacks and let it continue as asynchronous.

You can achieve it as follows:

private void getFirstUser(final ValueCallback<String> valueCallback){
String evS = "document.getElementsByClassName(\"hm-user\")[0].innerHTML";
final StringBuilder sb = new StringBuilder();
try{
evaluateJavascript(evS, valueCallback);
}catch (Exception e){
valueCallback.onReceiveValue(null);// You can pass any value instead of null.
};

}

While calling method simply do:

getFirstUser(new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
if(value != null && value.length() != 0 && !value.equals("null")){
//do something with proper value
}else{
// take necessary action if value is null
}

}
});


Related Topics



Leave a reply



Submit