添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
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 developer.android.com/reference/android/webkit/WebView.html is there a reason why loadData() or loadDataWithBaseURL() can't be used instead. – Morrison Chang Dec 26, 2016 at 3:05 As soon as I use load...() methods, it is breaking another functionality. So, I want to understand why calling load...() makes it all work in 19, 20, 21. – Ashok Bommisetti Dec 26, 2016 at 3:33

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.