onPageFinished在加载页面之前触发

时间:2014-07-07 10:38:38

标签: android android-webview

我只想知道何时加载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。当loadUrl启动时,正在加载html文件。当整个页面在屏幕上可用时,来自html文件的onload函数从JavaScriptInterface类调用captureImage函数。现在我确定页面已满载,我可以抓住它的图片。谢谢你的帮助。

代码:

JAVA:

    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>

5 个答案:

答案 0 :(得分:5)

这是因为onPageFinished表示“页面已完成加载”,而不是“页面在屏幕上”。不幸的是,WebView没有“你想要的页面现在在屏幕上”的API。人们通常会使用PictureListener(由于它不可靠而被弃用)和随机超时(超长或在某些设备上不起作用)的组合。

您可以尝试渲染到一个小位图,并检查每个PictureListener回调是否都是白色的(并且记得在等待完成后停止这样做,否则你将烧掉大量的CPU,如果页面有动画/ gifs / etc ..)。如果页面有大图像,渲染到小位图仍然会占用大量CPU资源,所以这绝对不是一个很好的解决方案。

答案 1 :(得分:1)

找到了一种简单的技术来加载页面,即使在调用onPageFinished之后, 递归调用loadUrl方法,直到页面未成功加载。 @Override public void onPageFinished(WebView view,String url){ // progressDialog.hide();

              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);
              }
          }

答案 2 :(得分:0)

try this :-


OnClickListener btnGoListener = new OnClickListener() {

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        webView00.loadUrl(etUrl.getText().toString());
        webView00.setWebViewClient(new WebViewClient() {

            public void onPageFinished(WebView view, String url) {
                Toast.makeText(getBaseContext(), "Loading Finished 2", Toast.LENGTH_LONG)
                .show();
            }
        });
    }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_web_page00);

    webView00 = (WebView) findViewById(R.id.webView00);
    btnGo = (Button) findViewById(R.id.go_btn);
    etUrl = (EditText) findViewById(R.id.url_edittext);

    webView00.getSettings().setJavaScriptEnabled(true);

    btnGo.setOnClickListener(btnGoListener);
    webView00.loadUrl("http://google.com");

    //webView00.setWebViewClient(new myWebViewClient());
    //webView00.setWebChromeClient(new myWebChromeClient());
    webView00.setWebViewClient(new WebViewClient() {

        public void onPageFinished(WebView view, String url) {
            Toast.makeText(getBaseContext(), "Loading Finished 1", Toast.LENGTH_LONG)
            .show();
        }
    });
}

答案 3 :(得分:0)

使用WebViewClientonPageFinished方法,如下所示:

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; 
   }

}
});

有关更多信息,请参阅https://stackoverflow.com/a/5172952/685240

希望它有所帮助。

编辑:根据您的评论,我认为您的网页已成功加载,但在屏幕上呈现/绘制网页需要时间,这是导致问题的原因。尝试为webview实施onPictureListener。有关更多参考,请参阅https://stackoverflow.com/a/18123023/685240

答案 4 :(得分:0)

在我看来,在WebViewClient中,回调onPageFinished在实际的window.load事件之前启动。

仍然在研究为什么会发生这种情况,这很难,因为Android应用程序是由一个高度定制的内部混合应用程序生成器生成的。

尽管如此,我已经通过实施一个安全措施来解决这个问题,该安全措施检查脚本中是否存在我想在onPageFinished中调用的错误,在这种情况下,我添加了一个事件处理程序,在此期间再次调用我的脚本window.load。

您也可以使用document.addEventListener(&#34; DOMContentLoaded&#34;,...)代替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);
        }