Android onPageFinished在加载页面之前触发

Android onPageFinished在加载页面之前触发,android,android-webview,Android,Android Webview,我只是想知道什么时候加载html页面。在加载整个页面之前调用OnPageFinished。当我通过从WebView创建的位图设置图像视图时,我得到了空白视图 mWebView.getSettings().setJavaScriptEnabled(true); mWebView.setAlwaysDrawnWithCacheEnabled(true); mWebView.setWebViewClient(new WebViewClient(){

我只是想知道什么时候加载html页面。在加载整个页面之前调用OnPageFinished。当我通过从WebView创建的位图设置图像视图时,我得到了空白视图

       mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.setAlwaysDrawnWithCacheEnabled(true);


  mWebView.setWebViewClient(new WebViewClient(){


            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon){

                super.onPageStarted(view, url, favicon);

            }



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

                    Bitmap b = Bitmap.createBitmap( 480, 240, Bitmap.Config.ARGB_8888);     
                    Canvas c = new Canvas(b);
                    view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
                    view.draw(c);
                    mImageView.setImageBitmap(b);


                 //b.recycle();
            }



        }); 
编辑:

我现在只尝试通过制作Toast消息来实现JavaScriptInterface,但它仍然不起作用。我粘贴了html代码和Java:

编辑:

我终于让它工作了。我使用了JavaScriptInterface和适当的接口。加载URL时,启动正在加载的html文件。当整个页面在屏幕上可用时,html文件中的onload函数调用JavaScriptInterface类中的captureImage函数。现在我已经确定该页面已完全加载,我可以抓取它的图片。谢谢你的帮助

代码:

爪哇:

    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.setDrawingCacheEnabled(true);
    mWebView.addJavascriptInterface(new JavaScriptInterface(this), "Android");
    mWebView.setWebViewClient(new WebViewClient(){});   
    mButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {


            mWebView.loadUrl("file:///android_asset/html_sample.html");
            //mWebView.loadUrl("https://www.onet.pl");

        }
    });

 public class JavaScriptInterface {
    private Context mContext;;

    public JavaScriptInterface(Context context) {
        mContext = context;
    }

    @JavascriptInterface
    public void captureImage(){

        Bitmap b = mWebView.getDrawingCache(true);
        mImageView.setImageBitmap(b);
    }

    @JavascriptInterface
    public void showToast(String toast) {
        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    }
}
HTML:

<html>
<head>
  <title>My first styled page</title>
  <link rel="stylesheet" href="sample_css.css">

</head>

<body onload="function(){ Android.captureImage() }">
...
</body>
</html>

我的第一个样式页面
...

使用
WebViewClient
onPageFinished
方法如下:

mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String urlNewString) {
   if (!loadingFinished) {
      redirect = true;
   }

loadingFinished = false;
webView.loadUrl(urlNewString);
return true;
}

@Override
public void onPageStarted(WebView view, String url) {
    loadingFinished = false;
    //SHOW LOADING IF IT ISNT ALREADY VISIBLE  
 }

@Override
public void onPageFinished(WebView view, String url) {
   if(!redirect){
      loadingFinished = true;
   }

   if(loadingFinished && !redirect){
     Bitmap b = Bitmap.createBitmap( 480, 240, Bitmap.Config.ARGB_8888);     
     Canvas c = new Canvas(b);
     view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
     view.draw(c);
     mImageView.setImageBitmap(b);
   } else{
      redirect = false; 
   }

}
});
有关更多信息,请参阅

希望能有帮助


编辑:根据您的评论,我认为您的页面加载成功,但在屏幕上呈现/绘制页面需要时间,这就是问题的原因。尝试为webview实现
onPictureListener
。有关更多参考信息,请参阅这是因为
onPageFinished
表示“页面已完成加载”,而不是“页面在屏幕上”。不幸的是,WebView没有“您想要的页面现在在屏幕上”API。人们通常采用PictureListener(由于不可靠而被弃用)和随机超时(超长或在某些设备上不起作用)的组合


您可以尝试渲染一个小位图,并检查每个
PictureListener
回调上的位图是否都是白色的(请记住在等待完成后停止此操作,否则如果页面有动画/GIF/等,您将消耗大量CPU)。如果页面有大图像,则渲染到小位图仍然会占用大量CPU,因此这肯定不是一个很好的解决方案。

我也遇到过这样的情况,即在WebViewClient中,在实际的window.load事件发生之前,在PageFinished上进行回调

仍在调查为什么有时会发生这种情况,这很难,因为android应用程序是由一个高度定制的内部混合应用程序生成器生成的

尽管如此,我还是克服了这个问题,实现了一个安全机制,检查我要在onPageFinished中调用的脚本中是否存在错误,在这种情况下,我添加了一个事件处理程序,在window.load期间再次调用我的脚本

您还可以使用document.addEventListener(“DOMContentLoaded”,…)而不是window.load

下面是一个示例代码段,也是debug.log调用的示例。您可以将调用作为参数传递给javascript接口

 private void executeOnLoad(final WebView view, final String jsStringToExecute) {
            StringBuilder sb = new StringBuilder("javascript:");
            sb.append("try {console.log('native.onPageFinished. document.readyState: ' + document.readyState);").append(jsStringToExecute).append("} catch(err){console.log('error calling jsBridge script on page load, deferring call to window.load event');")
            .append("window.addEventListener('load', function() {console.log('window.onload callled from native. document.readyState: ' + document.readyState);").append(jsStringToExecute).append("});").append("}");
            String jsWithWindowLoadedFallback = sb.toString();
            view.loadUrl(jsWithWindowLoadedFallback);
        }

找到了一种简单的技术,即使在调用onPageFinished之后也可以加载页面-- 递归调用loadUrl方法,直到页面未成功加载。。 @凌驾 公共void onPageFinished(WebView视图,字符串url){ //progressDialog.hide()


你能详细说明一下你想做什么吗?你的目标是什么API级别?HTML是否包含iFrame?等等。开始~API-12对WebView的内部更改开始破坏WebView。PictureListener…加载网页时一切正常,例如“”,但当我想加载存储在资源中的静态html文件时,在加载整个页面之前会触发onFinishedPage。是否有方法调用该页面?可能是从html?是否有可能使用html通知所有内容已加载?我编辑了我的帖子,如果我的方法不起作用,我将从编辑部分以您的方式实现请不要使用c
中的所有loadUrl都应该重写AllowReading
,因为它是针对具有非https方案的子帧调用的。如果您转到类似于代码的页面,则会调用view.loadUrl('tel:1234'),并最终显示错误页面,因为webview不知道如何加载tel:URL。
 private void executeOnLoad(final WebView view, final String jsStringToExecute) {
            StringBuilder sb = new StringBuilder("javascript:");
            sb.append("try {console.log('native.onPageFinished. document.readyState: ' + document.readyState);").append(jsStringToExecute).append("} catch(err){console.log('error calling jsBridge script on page load, deferring call to window.load event');")
            .append("window.addEventListener('load', function() {console.log('window.onload callled from native. document.readyState: ' + document.readyState);").append(jsStringToExecute).append("});").append("}");
            String jsWithWindowLoadedFallback = sb.toString();
            view.loadUrl(jsWithWindowLoadedFallback);
        }
              Log.e("onPageFinished","onPageFinished");
              if (view.getContentHeight() == 0){
                  pbar.setVisibility(View.VISIBLE);
                  webView.loadUrl("https://drive.google.com/viewerng/viewer?embedded=true&url="+pdf);

              }
              else {
                  pbar.setVisibility(View.GONE);
              }
          }