Android 通过onDraw方法从正在进行动画的自定义视图保存位图

Android 通过onDraw方法从正在进行动画的自定义视图保存位图,android,bitmap,Android,Bitmap,因此,我有一个动画,它是通过在自定义视图的onDraw()方法中绘制一组位图来创建的。有一个更新线程在自定义视图中调用一个方法,该方法更改onDraw()方法要绘制的位图的位置。我想做的是保存每次更新线程完成时创建的位图,以便可以从保存的位图创建gif 我发现下面的代码可以将存储在内存中的位图中的png保存到SD卡,并且可以与存储的位图一起使用,但getDrawingCache()有问题: public void saveView(){ 如果(计数器

因此,我有一个动画,它是通过在自定义视图的onDraw()方法中绘制一组位图来创建的。有一个更新线程在自定义视图中调用一个方法,该方法更改onDraw()方法要绘制的位图的位置。我想做的是保存每次更新线程完成时创建的位图,以便可以从保存的位图创建gif

我发现下面的代码可以将存储在内存中的位图中的png保存到SD卡,并且可以与存储的位图一起使用,但getDrawingCache()有问题:

public void saveView(){
如果(计数器<200){
试一试{
计数器++;
系统输出打印项次(“计数器:+计数器);
文件文件=新文件(路径,“星形”+计数器+“.png”);
delete();
OutputStream fOut=新文件OutputStream(文件);
buildDrawingCache();
getDrawingCache().compress(Bitmap.CompressFormat.PNG,100,fOut);
销毁DrawingCache();
fOut.flush();
fOut.close();
MediaStore.Images.Media.insertImage(context.getContentResolver()、file.getAbsolutePath()、file.getName()、file.getName());
}捕获(例外e){
e、 printStackTrace();
}
}
}
现在这样做基本上可以做两件事:

1) 它将拍摄大约50张图像并将其保存到sd卡中。@大约50,它会导致堆变大(我猜destroyDrawingCache()实际上无法完成,因为它在一个单独的线程中)

2) 在拍摄的照片中,您可以看到缓冲区中的扫描线正在更新,因为我是从更新的缓冲区中拍摄的

getDrawingCache似乎也调用了onDraw(),这就是为什么我不能在onDraw本身的UI线程上使用它


如果可能,请提供帮助。

您不应该从UI线程外部调用
getDrawingCache()
。这就是为什么您得到的位图部分更新了扫描线。直接从
onDraw()
调用
saveView()
。克隆缓存位图后,只能在单独的线程上运行文件操作

注意:你可以打电话吗?这样您就不必调用
buildDrawingCache()
destroyDrawingCache()
。此外,如果您的设备已启用硬件加速,则必须调用
setLayerType(LAYER\u TYPE\u SOFTWARE,null)


另一种解决方案是通过调用包含空白位图的新画布来获取位图。

是否在UI线程上调用了
saveView()
?每次调用onDraw时,它都不会出现在新线程中。当我从UI线程运行代码时,我得到的只是一遍又一遍的相同图像,它永远不会改变。这是使用setDrawingCacheAbled(true)而不是其他的。使用View.draw(canvas)是我必须做的路线。所以基本上我从更新方法调用了saveView。在saveview中,我制作了一个临时位图,并手动从绘制(画布)中获取构造的位图,然后发布并保存到sd。我扩展了图像切换器以捕获屏幕。在动画中,我覆盖了onDraw()方法,它根据需要拍照,但它不绘制我的视图(只是在某个时间闪烁),并且根本没有动画。我想知道它如何能够捕捉图像,但不能正确地绘制它?请帮忙。
public void saveView(){
    if(counter < 200){
        try {
            counter++;
            System.out.println("Counter : " + counter);
            File file = new File(path, "star"+counter+".png");
            file.delete();
            OutputStream fOut = new FileOutputStream(file);
            buildDrawingCache();
            getDrawingCache().compress(Bitmap.CompressFormat.PNG, 100, fOut);
            destroyDrawingCache();
            fOut.flush();
            fOut.close();
            MediaStore.Images.Media.insertImage(context.getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}