Android 使用WebView加载含有echarts的页面,截图不显示的解决方式

问题原因:

其主要原因:是webview渲染方式所导致;只需要AndroidManifest.xml中设置属性Android:hardwareAccelerated=”false”。

由于WebView内部所使用的Chromium实现是采用硬件加速渲染还是软件渲染,这里还是比较复杂的。根据android的View结构,WebView的内容需要通过一个onDraw(Canvas c)来完成绘制。为了将Chromium渲染网页的结果绘制到该Canvas中,需要两组绘图函数组,第一组用来软件渲染,第二组用来硬件加速渲染。而这两组函数需要使用Android内部函数,这决定了目前WebView只能同Android AOSP代码一起编译,而不能像应用程序一样,只是依赖于Android SDK/NDK来编译。下图是当用户界面或者网页需要绘制的时候,绘图的基本过程: 

 
这里Chromium的合成器具有两种能力,就是包含支持软件渲染的软件渲染器和硬件加速渲染的渲染器。当用户界面所对应的画布(canvas)是硬件加速的话,那么内部采用硬件渲染机制。如果不是硬件加速的话,那么采用软件渲染机制。当用户的界面设置为硬件加速的时候(开发者可以在应用程序的AndroidManifest.xml中设置属性android:hardwareAccelerated=”true”),那么用户界面对应的画布即为硬件加速,否则即为软件渲染方式。所以,具体Chromium WebView采用什么样的方式,取决于调用WebView的应用程序的设置方式(默认是硬件加速)。 (关闭硬件加速会很卡顿,体验不好,不推荐)
————————————————
版权声明:本文为CSDN博主「ge673551532」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ge673551532/article/details/76103686

解决思路,录屏取其中的一帧为截图;

2. 截取非含当前应用的屏幕部分(最佳官方方案)

​ Android 在5.0 之后支持了实时录屏的功能。通过实时录屏我们可以拿到截屏的图像。同时可以通过在Service中处理实现后台的录屏。具体的类讲解大家自行网上查阅。

大体步骤:

1.初始化一个MediaProjectionManager。


MediaProjectionManager mMediaProjectionManager = (MediaProjectionManager)getApplication().getSystemService(Context.MEDIA_PROJECTION_SERVICE);

2.创建intent,并启动Intent。注意这里是startActivityForResult


startActivityForResult(mMediaProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);

3.在onActivityResult中拿到Mediaprojection。

mResultCode = resultCode;

mResultData = data;

mMediaProjection = mMediaProjectionManager.getMediaProjection(mResultCode, mResultData);

4.设置VirtualDisplay 将图像和展示的View关联起来。一般来说我们会将图像展示到SurfaceView,这里为了为了便于拿到截图,我们使用ImageReader,他内置有SurfaceView。

mImageReader = ImageReader.newInstance(windowWidth, windowHeight, 0x12); //ImageFormat.RGB_565

mVirtualDisplay = mMediaProjection.createVirtualDisplay("screen-mirror",

        windowWidth, windowHeight, mScreenDensity,       DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,

        mImageReader.getSurface(), nullnull);

5.通过ImageReader拿到截图

strDate = dateFormat.format(new java.util.Date());
nameImage = pathImage + strDate + ".png";
Image image = mImageReader.acquireLatestImage();
int width = image.getWidth();
int height = image.getHeight();
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * width;
Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
image.close();
Log.i(TAG, "image data captured");
if (bitmap != null) {
    try {
        File fileImage = new File(nameImage);
        if (!fileImage.exists()) {
            fileImage.createNewFile();
            Log.i(TAG, "image file created");
        }
        FileOutputStream out = new FileOutputStream(fileImage);
        if (out != null) {
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
            out.close();
            Intent media = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            Uri contentUri = Uri.fromFile(fileImage);
            media.setData(contentUri);
            this.sendBroadcast(media);
            Log.i(TAG, "screen image saved");
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

6.注意截屏之后要及时关闭VirtualDisplay ,因为VirtualDisplay 是十分消耗内存和电量的。

private void stopVirtual() {
    if (mVirtualDisplay == null) {
        return;
    }
    mVirtualDisplay.release();
    mVirtualDisplay = null;
    Log.i(TAG, "virtual display stopped");
}

参考:https://github.com/VincentWYJ/CaptureScreen

原文链接:Android实现截屏方式_zhangcanyan的博客-CSDN博客_android 截图

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值