Could someone once and for all please explain Cann

2019-04-20 07:45发布

问题:

I'm currently working on graphing data via d3 into a webview. Naturally, things are breaking as soon as I try to reload the graph and feed it new data. This lovely line keeps popping up: W/cr_BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid.

I've scoured SO for an explanation, but there doesn't seem to be anything conclusive. People are just suggesting to turn on DOM storage in webview settings (which obviously doesn't fix the issue). I'm suspecting there is a race condition between reloading the graph and feeding it new data. I've overridden onPageFinished() in my WebViewClient to call the listener to load the data into the chart, thinking it would resolve the race condition, but to no avail.

Can someone please explain to me what W/cr_BindingManager: Cannot call determinedVisibility() - never saw a connection for the pid means? Am I off in my assessment? How can I debug it?

Any tips are appreciated.

EDIT: I've solved the original issue, but I would still love to learn what that line means. Bounty up.

回答1:

Consecutive calls to loadUrl cause a race condition. The problem is that loadUrl("file://..") doesn't complete immediately, and so when you call loadUrl("javascript:..") it will sometimes execute before the page has loaded.
This is how I setup my webview:

wv = (CustomWebView) this.findViewById(R.id.webView1);

WebSettings wv_settings = wv.getSettings();

//this is where you fixed your code I guess
//And also by setting a WebClient to catch javascript's console messages :

wv.setWebChromeClient(new WebChromeClient() {
        public boolean onConsoleMessage(ConsoleMessage cm) {
            Log.d(TAG, cm.message() + " -- From line "
                    + cm.lineNumber() + " of "
                    + cm.sourceId() );
            return true;
        }
    });
wv_settings.setDomStorageEnabled(true);

wv.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            setTitle(view.getTitle());
            //do your stuff ...
            }
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("file")) 
        {
            // Keep local assets in this WebView.
             return false;
        }
      }
    });

//wv.setWebViewClient(new HelpClient(this));//
wv.clearCache(true);
wv.clearHistory();
wv_settings.setJavaScriptEnabled(true);//XSS vulnerable
wv_settings.setJavaScriptCanOpenWindowsAutomatically(true);
wv.loadUrl("file:///android_asset/connect.php.html");

NOTE this line wv.setWebChromeClient(new WebChromeClient());

In API level 19 (Android 4.4 KitKat), the browser engine switched from Android webkit to chromium webkit, with almost all the original WebView API's wrapped to the counterparts of chromium webkit.

This is the method that gives the error (BindingManagerImpl.java), from Chromium source:

@Override
public void determinedVisibility(int pid) {
    ManagedConnection managedConnection;
    synchronized (mManagedConnections) {
        managedConnection = mManagedConnections.get(pid);
    }
    if (managedConnection == null) {
        Log.w(TAG, "Cannot call determinedVisibility() - never saw a connection for the pid: "
                + "%d", pid);
        return;
    }


It's a rendering warning from content.
You can dig around forever in that github source code, might be nice to see where the method determinedVisibility (in BindingManagerImpl.java) is called from...(suffix “Impl” for Implementation). Hope this helps ;O)



回答2:

This usually pops up when you are overriding the method shouldOverrideUrlLoading().

From my WebView usages on prior apps, this is due to what is being rendered on the WebView, what is being caught on the above method and in turn ignored. I see this a lot when the websites that I load attempt to load scripts outside of the allowed domain.