Android Webview:在渲染完成时检测

lol*_*shi 17 android snapshot android-webview

我想在加载WebView后对WebView进行快照.但是,返回的位图始终为null,因为即使我使用了渲染也未完成加载onPageFinished.我在互联网上搜索,人们建议使用WebView.PictureListener,但在API 12中不推荐使用此功能.

一些代码

public class MainActivity extends Activity {
    private WebView mButterflyWebView;

    /**
     * Gets html content from the assets folder.
     */
    private String getHtmlFromAsset() {
        InputStream is;
        StringBuilder builder = new StringBuilder();
        String htmlString = null;
        try {
            is = getAssets().open(getString(R.string.butterfly_html));
            if (is != null) {
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(is));
                String line;
                while ((line = reader.readLine()) != null) {
                    builder.append(line);
                }

                htmlString = builder.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return htmlString;
    }

    /**
     * Initializes views, controls...
     */ 

    private void init() {
        mButterflyWebView = (WebView) findViewById(R.id.butterfly_webview);

        mButterflyWebView.setWebChromeClient(new WebChromeClient() {
        public void onProgressChanged(WebView view, int newProgress) {


            if (newProgress == 100){
                if (capturePictureWebView() != null){
                    saveBitmapToFile(capturePictureWebView());
                }
            }
        }
    });

    }

    /**
     * Loads html page with the content.
     */
    private void loadHtmlPage() {
        String htmlString = getHtmlFromAsset();
        if (htmlString != null)
            mButterflyWebView.loadDataWithBaseURL(
                    "file:///android_asset/images/", htmlString, "text/html",
                    "UTF-8", null);

        else
            Toast.makeText(this, R.string.no_such_page, Toast.LENGTH_LONG)
                    .show();
    }

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        init();
        loadHtmlPage();
    }

    private Bitmap capturePictureWebView() {
        mButterflyWebView.measure(MeasureSpec.makeMeasureSpec(
                MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED),
                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        mButterflyWebView.layout(0, 0, mButterflyWebView.getMeasuredWidth(),
                mButterflyWebView.getMeasuredHeight());
        mButterflyWebView.setDrawingCacheEnabled(true);
        mButterflyWebView.buildDrawingCache();

        if (mButterflyWebView.getMeasuredWidth() == 0 || mButterflyWebView.getMeasuredHeight() == 0){
            return null;
        }
        Bitmap bm = Bitmap.createBitmap(720, 1280, Bitmap.Config.ARGB_8888);

        System.out.println("width=" + mButterflyWebView.getMeasuredWidth());
        System.out.println("height=" + mButterflyWebView.getMeasuredHeight());
        Canvas bigcanvas = new Canvas(bm);
//        bigcanvas.scale(720/mButterflyWebView.getMeasuredWidth(), 1280/mButterflyWebView.getMeasuredHeight());
        Paint paint = new Paint();
        int iHeight = bm.getHeight();
        bigcanvas.drawBitmap(bm, 0, iHeight, paint);
        mButterflyWebView.draw(bigcanvas);
        return bm;
    }

    private void saveBitmapToFile(Bitmap bitmap) {
        try {

            FileOutputStream out = new FileOutputStream("/storage/sdcard0/a.png");
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

And*_*ros 11

您应该尝试使用WebChromeClient并实现onProgressChanged:

http://developer.android.com/reference/android/webkit/WebChromeClient.html#onProgressChanged(android.webkit.WebView,int)

mButterflyWebView.setWebChromeClient(new WebChromeClient() {

        @Override
        public void onProgressChanged(WebView view, int progress) {
           if (progress == 100) {
               // do screenshot
           }
        }
});
Run Code Online (Sandbox Code Playgroud)

编辑:检查是否多次加载onPageStarted:

mButterflyWebView.setWebViewClient(new WebViewClient() {

        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
           Log.d("WebView", "onPageStarted " + url);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
           Log.d("WebView", "onPageFinished " + url);
        }
    });
Run Code Online (Sandbox Code Playgroud)

  • 不起作用,尽管newProgress = 100,渲染还没有完成.还有什么? (6认同)

Fra*_*ank 5

你可以在你的 WebView 中这样做:

@Override
public void invalidate() {
    super.invalidate();

    if (getContentHeight() > 0) {
        // WebView has displayed some content and is scrollable.
    }
}
Run Code Online (Sandbox Code Playgroud)

感谢:https : //stackoverflow.com/a/14678910/1310343


Dan*_*vak 5

检测页面是否已呈现的最佳方法是使用API 23提供的onPageCommitVisible回调onPageLoadFinished,因为它交付的时间太早(在处理HTML但尚未呈现HTML时),因此不适合。

webview.setWebViewClient(new WebViewClient(){

    @Override
     public void onPageCommitVisible (WebView view, 
            String url)
    }
Run Code Online (Sandbox Code Playgroud)

}

  • 我不同意。我发现触发了以下序列:`onPageCommitVisible` -> `onProgressChanged` -> `onPageFinished` (3认同)

lol*_*shi 2

最后我得到了这个问题的非常详细的信息。这解释了为什么它总是返回空位图。

我的应用程序中的每个更改都是由用户操作触发的,因此我想出了一个修改版本,仅在 touchEvent 之后触发 invalidate()

感谢您的所有帮助。

Android WebView 呈现空白/白色,视图不会因 css 更改或 HTML 更改而更新,动画断断续续