如何将通过WebView呈现的html页面保存到位图中,而WebView是使用Theme.NoDisplay的活动的一部分?

时间:2015-09-17 19:15:47

标签: android webview themes

我知道如何做到这一点,而WebView是可见活动的一部分。我有自己的MyWebView类扩展WebView。在那里,我有自己的覆盖onDrawinvalidate方法(见下文)。这似乎运作良好。

public class MyWebView extends WebView {
    private static final String TAG = MyWebView.class.getName();

    private Canvas offscreen;
    private Bitmap bitmap = null;

    public MyWebView(Context context) {
        super(context);
    }

    public MyWebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public MyWebView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // We want the superclass to draw directly to the offscreen canvas
        // so that we don't get an infinitely deep recursive call
        if(canvas == offscreen) {
            super.onDraw(offscreen);
        } else {
            //Our offscreen image uses the dimensions of the view rather than the canvas
            bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
            offscreen = new Canvas(bitmap);
            super.onDraw(offscreen);
            Log.d(TAG, "Drew canvas into a bitmap");
        }
    }

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

        if ((getContentHeight() > 0) && (getProgress() == 100)) {
            // WebView has displayed some content
            // Now is the time to store the bitmap into a file
            FileOutputStream fos = null;
            String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator + "image.jpeg";
            File imageFile = new File(path);

            try {
                fos = new FileOutputStream(imageFile);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                fos.close();
                Log.i(TAG, "Image stored into : " + path);
            } catch (Exception e) {
                String eMessage = "Unable to save the image into: " + e.toString();
                Log.e(TAG, eMessage);
            } finally {
                try {
                    if (fos != null) {
                        fos.close();
                    }
                } catch (Exception e) {
                    String eMessage = "Something went really wrong. Unable to close FileOutputStream: " + e.toString();
                    Log.e(TAG, eMessage);
                }
            }
        }
    }
}

我需要在没有UI的活动中执行此操作,例如将主题设置为Theme.NoDisplay的活动。

有人可以帮我吗?

对于主题设置为Theme.NoDisplay的活动,似乎永远不会调用onDraw方法,而多次调用invalidate

即使在没有UI的活动中,如何强制系统调用onDraw方法?

我也很高兴任何其他方法如何将html页面呈现/保存到位图中。所有这些都必须作为后台任务发生,而用户甚至不会注意到它。 WebView可能不是必须的,但对我来说似乎非常有用。

1 个答案:

答案 0 :(得分:0)

经过我的调查,解决方案如下:

我必须直接调用WebView的draw方法。这样,也会调用onDraw方法并创建位图。问题在于何时何地调用draw方法。

经过无休止的onPageFinished实验,javascript界面​​听取onload事件和其他人我无法找到一个优雅的解决方案。没有什么真正起作用,因为所有钩子都是在资源物理上在设备上之前触发的。所以位图一直是空的。

所以最后它对我有用的唯一方法就是当我在onPageFinished中调用draw方法时有一些延迟。我实际创建了自己的draw方法,它不带任何参数。这个简单地使用位图画布调用WebView的方法。

Parse.Object

它适用于我测试过的所有设备(即使是像Jelly Beans这样的旧版本)。

我能用这个解决方案看到的唯一问题是

  • 一旦页面资源真正完全加载到WebView中,我没有立即获得图像(我真的不知道我应该坚持什么样的事件。我现在怀疑谷歌没有一个可靠的Android版本)。
  • 我有一个看不见的活动,每当我需要创建一个图像时,它会挂在系统中2秒钟