【问题标题】:onPageFinished not firing correctly when rendering web page渲染网页时 onPageFinished 未正确触发
【发布时间】:2019-09-05 20:03:41
【问题描述】:

由于某种原因,onPageFinished 在 WebView 完成加载之前触发 - 我不知道为什么......

public class WebViewClientTest extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    final WebView webview = (WebView) findViewById(R.id.webview);

    webview.setWebViewClient(new WebViewClient() {  
        @Override  
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(webview, url);
            webview.scrollTo(0, 500);
        }  
    });
    webview.loadUrl("http://www.google.co.uk/search?sourceid=chrome&ie=UTF-8&q=lala");

}
}

好的,看来这不是固定的。我认为加载页面时会出现竞争情况,但无法获得可重现的行为。

我将网页的 HTML 内容存储在 SQLite 数据库中,以便在离线时查看。我将内容重新加载到 WebView 中:

webView.loadDataWithBaseURL("fake://fake.com/", htmlBody, "text/html", "utf-8", null);

似乎有时当 WebView 加载时它会正确触发 WebViewClient.onPageFinished() 方法,而其他时候则不会。有时它似乎在页面完成加载之前触发,产生 0 的 contentHeight 并忽略任何 scrollTo 调用。

有人有这方面的经验吗?

【问题讨论】:

    标签: java android webkit


    【解决方案1】:

    我有一个项目,它的代码只有在 webview 显示其内容后才需要运行,并且像你一样,onPageFinished() 不起作用。在 webview 实际呈现页面之前,它触发得太快了。

    相反,我不得不使用“PictureListener”,它会在 webview 实际更新屏幕时触发。

    你这样使用它:

    mWebView.setPictureListener(new MyPictureListener());
    //... and then later on....
    class MyPictureListener implements PictureListener {
    
        @Override
        public void onNewPicture(WebView view, Picture arg1) {
          // put code here that needs to run when the page has finished loading and
          // a new "picture" is on the webview.      
        }    
    } 
    

    【讨论】:

    • 完美 - 谢谢!只是想补充一点,即使在滚动事件完成后,这个 onNewPicture 也会触发,所以我需要围绕这个编写代码,但上面的工作完美。
    • 除了现在已弃用(平板电脑助手 - 天堂):( 所以我使用了一个 javascript 调用,它在返回时间方面优于 WebChromeClient onProgressChanged()...只需要注意哪个当你得到回报时你正在操作的线程(我使用 WebView 的处理程序和延迟调用)——话虽如此,我想看看 WebChromeClient.onProgressChanged() 的表现如何
    • 有没有更好的方法来做到这一点
    • @Dan 你能详细说明你的 Javascript 调用吗?代码 sn-p 将是超级的。感谢并同时 +1。
    • 好吧,当我尝试这个时,应用程序问我你想为这个网站“chrome”或“internet”使用哪个应用程序。这意味着,您的解决方案会打开外部浏览器。至少,对我来说..
    【解决方案2】:

    在呈现我的网页时,我在关闭我的进度对话框时遇到了同样的问题。我用 onPageStarted 解决了。 我希望这个解决方案可以帮助你。

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
    
            progressBar.dismiss();
    
        }
    
        @Override
        public void onPageStarted(WebView view, String url,
                android.graphics.Bitmap favicon) {
    
            if (!progressBar.isShowing()) {
                progressBar.show();
            }
        };
    

    【讨论】:

    • 这个对我有用。我有一个覆盖 URL 加载的 webview。
    【解决方案3】:

    嗯,如果我自己开设私人课程,它就可以了...

    private class ViewStoryWebViewClient extends WebViewClient { 
        @Override  
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(webView, url);
            webView.scrollTo(0, 50);
        }  
    } 
    

    【讨论】:

    • 这发生得太快了,在图片渲染之前
    【解决方案4】:

    loadDataWithBaseURL() 得到了完全相同的结果。有时内容不显示并且 contentHeight 为 0。奇怪的是,单击 Web 视图中的任何位置都会导致显示内容。另外,如果你在onPageFinished()方法中调用zoomIn();zoomOut();,也会出现页面。

    编辑:我的代码的问题是 HTML 内容在 onload 事件中有一个虚拟的 window.location= 分配,这导致原始内容不能随机加载。抱歉,我认为这与您所看到的无关。

    【讨论】:

      【解决方案5】:

      在过去的 6 个小时里,我一直在寻找答案,终于找到了一个至少对我有用的答案,而且答案很简单。一个计时器。 在您的 OnPageFinished 启动计时器后,只要您愿意,就我而言,我做了 2 秒。这将有足够的时间让 webview 渲染和加载整个页面。 如果要调用 webview 方法,请确保在 UI 线程上运行计时器

            Timer myTimer = new Timer(); //global variable
      
            public void startTimer(TimerTask t){
                myTimer.scheduleAtFixedRate(t,2000,2000);
            }
      
      
                 ....
                    public void onPageFinished(WebView view, String url) {                          
                        TimerTask task = new TimerTask() {
                            @Override
                            public void run() {
                              //stuff to do after page is fully loaded
                              myTimer.cancel();
                            }
                        };
                        startTimer(task);
                    }
      

      顺便说一句,这是我对 stackoverflow 的第一个回答。希望这对某人有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-19
        • 1970-01-01
        • 2013-03-03
        • 2012-09-30
        • 2012-11-28
        • 1970-01-01
        相关资源
        最近更新 更多