Android WebView onPageCommitVisible не запущен

У меня есть WebView, который загружает html-страницу с сервера, но страница невидима в WebView. HTML-код загружается правильно (я отлаживал с помощью chrome://inspect и html, включая все существующие javascripts), но он невидим на экране телефона. В моем коде не было никаких изменений, когда появилась эта ошибка. Ошибка появилась, когда я установил обновления для Android System WebView на свой телефон. Если я удалю обновления, все снова работает правильно. Кроме того, я проверил обратные вызовы WebViewClient и заметил, что onPageCommitVisible не вызывается. Так почему-то страница не загружается должным образом. Только если я нажму кнопку «Назад», чтобы выйти из WebView, я увижу, что onPageCommitVisible вызывается для моей веб-страницы (но это не помогает, поскольку кнопка «Назад» существует в WebView, как и ожидалось).

Вот мой код для веб-просмотра:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    RelativeLayout rlMain = new RelativeLayout(getActivity());
    rlMain.setContentDescription(Constants.STARTAPP_AD_MAIN_LAYOUT_CONTENT_DESCRIPTION);
    rlMain.setId(Constants.MAIN_LAYOUT_ID);
    getActivity().setContentView(rlMain);

    // Create WebView and set its parameters
    try{
        webView = new WebView(getActivity().getApplicationContext());
        webView.setBackgroundColor(0xFF000000);
        getActivity().getWindow().getDecorView().findViewById(android.R.id.content).setBackgroundColor(0x00777777);
        webView.setVerticalScrollBarEnabled(false);
        webView.setHorizontalScrollBarEnabled(false);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.setWebChromeClient(new WebChromeClient());
        // set software acceleration
        if (softwareAcceleration) {
            ApiUtil.setWebViewLayerTypeSoftware(webView, null);

        } 

        webView.setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                return true;
            }
        });
        webView.setLongClickable(false);

        webView.addJavascriptInterface(createJsInterface(), Constants.INTERFACE);

        setWebViewSpecificParameters(webView);  


        webView.loadDataWithBaseURL("http://www.xxxxxx.com", getHtml(), "text/html", "utf-8", null);


        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            WebView.setWebContentsDebuggingEnabled(true);
        }
        webView.setWebViewClient(new MyWebViewClient());

        RelativeLayout.LayoutParams webviewPrms = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT,
                RelativeLayout.LayoutParams.MATCH_PARENT
            );
        rlMain.addView(webView, webviewPrms);
}

public void setWebViewSpecificParameters(final WebView webView) {
        webView.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                return (event.getAction() == MotionEvent.ACTION_MOVE);
            }
        });
}

private class MyWebViewClient extends WebViewClient {


        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
            Logger.log(TAG, Log.DEBUG, "!!!!!shouldInterceptRequest" );
            return super.shouldInterceptRequest(view, url);
        }

        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
            Logger.log(TAG, Log.DEBUG, "!!!!!shouldInterceptRequest" );
            return super.shouldInterceptRequest(view, request);
        }


        @Override
        public void onPageFinished(WebView view, String url) {
            setWebViewBackground(view);
            runJavascript(Constants.JAVASCRIPT_SET_MODE_SERVER, getPosition());
            runJavascript(Constants.JAVASCRIPT_ENABLE_SCHEME, "externalLinks");
            InterstitialMode.this.onWebviewPageFinished();

        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            return clicked(url);
        }
    }

person user2924714    schedule 18.05.2016    source источник
comment
Проблема была решена в последней версии, выпущенной Android System Web View. Так что это была ошибка в веб-просмотре   -  person user2924714    schedule 20.06.2016
comment
Привет, ты нашел решение для этого?   -  person Rajitha Perera    schedule 09.05.2019


Ответы (1)


В приложении, которое переходит с одного веб-сайта на другой на основе пользовательского ввода, существует высокая вероятность (> 50 %), что второй веб-сайт вообще не будет отображаться после вызова WebView.loadUrl, а предыдущий веб-сайт остается видимым — он даже интерактивен, т. е. прокручивается. работает. Проблема обычно решается после повторного вызова WebView.loadUrl. Нет очевидных признаков возникновения ошибки, кроме того, что пользователь не видит второй веб-сайт. Полагаться на то, что пользователь перезагрузит страницу вручную, не является удовлетворительным решением, поскольку ошибка возникает довольно часто.

Я смог обойти эту проблему, используя пользовательский WebViewClient, чтобы обнаружить, что второй веб-сайт не был загружен должным образом, и вызвать перезагрузку:

        setWebViewClient(new WebViewClient() {

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    buggyWebViewHandler.postDelayed(new Runnable() {

                        @Override
                        public void run() {
                            if (!wasCommitCalled) {
                                loadUrl(url);
                            }
                        }
                    }, 2500);
                }
            }

            @Override
            public void onPageCommitVisible(WebView view, String url) {
                wasCommitCalled = true;
            }
        });

Где buggyWebViewHandler — это Handler или любой другой класс, который позволяет отложить часть кода на какое-то время. Кроме того, вам нужно будет установить wasCommitCalled = false; всякий раз, когда вызывается WebView.loadUrl, например, путем переопределения метода.

Обратите внимание, что это работает только для Android 23 и выше, потому что именно тогда был добавлен onPageCommitVisible. Полную реализацию см. здесь: https://github.com/TomTasche/OpenDocument.droid/blob/8c2eec5c57e5962e9ac4c46549be2241b259eb32/app/src/main/java/at/tomtasche/reader/ui/widget/PageView.java#L72-L96

Если у кого-то хватит смелости копнуть глубже, почему это происходит: при отладке казалось, что onPageStarted не вызывается всякий раз, когда возникает эта ошибка. Может быть, это поможет...

person TomTasche    schedule 01.03.2020