Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onPageFinished is firing before page is loaded

I just want to know when html page is loaded. OnPageFinished is called before whole page is loaded. I got blank view when I set Image View by bitmap created from 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();
            }



        }); 

EDIT :

I tried to implement JavaScriptInterface for now only with making Toast message, but it still doesn't work. I've pasted html code and Java :

EDIT :

I finally got it working. I used JavaScriptInterface with proper . When loadUrl is launch html file is being loaded. When whole page is available on screen, onload function from html file call captureImage function from JavaScriptInterface class. Now I have sure that page is fully loaded and I can grab picture of it. Thanks for all help.

CODE:

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>
like image 657
dzakens Avatar asked Jul 07 '14 10:07

dzakens


2 Answers

Found simple technique to load page even after onPageFinished is called-- Recursively call loadUrl method until page is not loaded successfully.. @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);
              }
          }
like image 31
Sachin Deshapande Avatar answered Oct 07 '22 12:10

Sachin Deshapande


This is because onPageFinished means "the page has finished loading", not "the page is on screen". Unfortunately the WebView doesn't have a 'the page you wanted is now on screen' API. Folks usually resort to a combination of PictureListener (which was deprecated since it's unreliable) and random timeouts (which are either super long or don't work on some devices).

You could try by rendering to a small bitmap and checking if it's all white on every PictureListener callback (and remember to stop doing this when you're done waiting, otherwise you'll burn tons of CPU if the page has animations/gifs/etc..). Rendering to a small bitmap will still be very CPU-intensive if the page has big images, so this is definitely not a great solution.

like image 191
marcin.kosiba Avatar answered Oct 07 '22 11:10

marcin.kosiba