Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
evaluateJavascript(String script, ValueCallback<String> resultCallback)
method is added to WebView on Android in SDK 19.
Android documentation quotes:
If non-null, resultCallback will be invoked with any
result returned from that execution.
I am using this method as shown below, but somehow my callback is not being invoked. I can see from debugging that the
evaluateJavascript()
is called, but the call back is not being invoked in Android API
19, 20 & 21
. From API 22 (LOLLIPOP_MR1) onwards, everything is working as expected.
Calling
webview.loadURL("")
before
evaluateJavascript()
makes it work on all the API levels. I want to understand why and would appreciate if somebody can shed some light / share any links about this. If I can understand why, I want to see if calling
loadURL()
could be avoided. There is another unrelated problem which makes
loadURL()
a non-preferable solution.
Code:
private void webViewTest() {
WebView webview = new WebView(this);
webview.getSettings().setJavaScriptEnabled(true);
Log.d("TEST", "BEFORE"); // LOGGED
// webview.loadUrl(""); // Enabling this makes it work on all Android versions
webview.evaluateJavascript("(function(){return 'test'})()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("TEST", "From JS: " + s); // NEVER LOGGED on API 19-21
Log.e("TEST", "AFTER"); // LOGGED
runOnUiThread(new Runnable() {
@Override
public void run() {
webViewTest();
Please find an example of this problem at https://github.com/bashok001/TestApp
–
–
From the docs:
Asynchronously evaluates JavaScript in the context of the currently displayed page. In ContentViewCore
EvaluateJavascript
checks for renderview. Looks like for that particular versions of WebView
integrated within 19,20,21 - the RenderView
is just not created until loadUrl
get called.
I found following FIX that could be relevant:
It's modify WebContentsAndorid native implementation of EvaluateJavaScript from :
void WebContentsAndroid::EvaluateJavaScript(JNIEnv* env,
jobject obj,
jstring script,
jobject callback,
jboolean start_renderer) {
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
DCHECK(rvh);
if (start_renderer && !rvh->IsRenderViewLive()) {
if (!static_cast<WebContentsImpl*>(web_contents_)->
CreateRenderViewForInitialEmptyDocument()) {
void WebContentsAndroid::EvaluateJavaScript(JNIEnv* env,
jobject obj,
jstring script,
jobject callback) {
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
DCHECK(rvh);
if (!rvh->IsRenderViewLive()) {
if (!static_cast<WebContentsImpl*>(web_contents_)->
CreateRenderViewForInitialEmptyDocument()) {
And in ContentViewCore
there was following code which passing false
as start_renderer
:
public void evaluateJavaScript(String script, JavaScriptCallback callback) {
assert mWebContents != null;
mWebContents.evaluateJavaScript(script, callback, false);
This mean that on WebView
built prior to mentioned fix calls to evaluateJavaScript
does not create RenderView
and as result WebContext
can't handle java script execution.
So when you use loadUrl
you force creation of render view and all starts working as expected.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.