【问题标题】:ArrayList<Bitmap> returns same bitmapArrayList<Bitmap> 返回相同的位图
【发布时间】:2014-10-13 16:27:43
【问题描述】:

我正在尝试使用Timer 定期捕获多个屏幕截图。 但;添加到ArrayList 的图像都是最后的图像。所以我在整个列表中都得到了类似的图像。

Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {

    @Override
    public void run() {
        handler.post(new Runnable() {

            @Override
            public void run() {

                System.out.println("executing timer "+index);

                View rootView = findViewById(R.id.relative_inside);
                rootView.setDrawingCacheEnabled(true);
                rootView.buildDrawingCache();

                Bitmap drawingCache = rootView.getDrawingCache();
                list.add(drawingCache);

                System.out.println("image added to list "+index);
                index++;
            }
        }); 
    }
};

我正在使用以下代码调用计时器:-

timer.schedule(timerTask, 0, 80);

但是,在从 List 中提取图像时,我得到了相似的图像。谁能指出我的错误?

【问题讨论】:

  • 列表对象在哪里定义?
  • ArrayList list = new ArrayList();在 Activity 中定义。

标签: android arraylist timer bitmap screen-capture


【解决方案1】:

这是因为getDrawingCache() 返回Bitmap 的相同实例,只是更新了像素数据。因此,所有已添加的列表项都会在缓存位图更改时更新。

每次读取缓存时都必须创建新的 Bitmap 实例,然后添加到列表中。

例如:

Bitmap drawingCache = Bitmap.createBitmap(rootView.getDrawingCache());
list.add(drawingCache);

请注意,位图消耗大量内存,很容易得到OutOfMemoryError

另外,你可以移动这部分:

View rootView = findViewById(R.id.relative_inside);
rootView.setDrawingCacheEnabled(true);
rootView.buildDrawingCache();

到 TimerTask 创建阶段,例如内部构造函数。然后您可以通过实例变量引用您的视图。遍历视图层次结构非常耗时。

【讨论】:

  • 如果我存储大约 111-112 张图像,那么它可以工作,但是随着总数达到 125 张图像,它会抛出 OutOfMemoryError 异常。我能做些什么呢?
  • 您可以在清单中设置 android:largeHeap 但大多数情况下不建议这样做。不幸的是,应用程序的内存有限,而位图是消耗最多的应用程序。如果您真的需要一次使用所有这些位图,那么您必须以不同的方式设计您的应用程序。如果没有,请考虑将这些位图存储在文件系统中,并在需要显示时使用缓存机制 developer.android.com/training/displaying-bitmaps/… 或 Picasso 等现有库,以实现高效的位图呈现。
  • 我需要所有这些位图供以后使用。我将在我的整个动画执行后保存所有这些位图。你以什么不同的方式要求我修改我的应用程序。请详细说明。
  • 有时技术限制不允许执行某些以设计更改结束的任务。这取决于应用程序,但似乎并非如此。如果您以后需要这些位图,则在存储后立即存储它们释放位图。然后优化动画中位图的使用,一次使用尽可能多的位图。为此,您必须熟悉缓存位图,请参阅先前评论中的链接。这是一项复杂的任务,我无法为您提供开箱即用的解决方案。
【解决方案2】:

我认为getDrawingCache()返回的位图总是一样的,只要你不回收位图或不调用setDrawingCacheEnabled(false);destroyDrawingCache()

【讨论】:

    猜你喜欢
    • 2014-05-01
    • 2012-07-05
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多