Bitmap对象是否通过引用保存在内存中?

时间:2015-07-28 13:04:41

标签: java android pointers object bitmap

请原谅我可能是一个非常令人难以置信的问题(我对Java和Android Studio都很陌生)。我来自C背景,目前正在使用Android Studio为Google Play开发移动应用。该应用程序将需要为游戏创建许多敌人对象。

考虑以下为敌方对象创建位图的方法;

在GamePanel类中(父级是SurfaceView,实现SurfaceHolder.Callback);

enemy = new Enemy(BitmapFactory.decodeResource(getResources(), R.drawable.enemy_pic));

在Enemy类中,我们的图像被声明为实例变量;

private Bitmap image;

然后我们在构造函数中初始化它(picResource是构造函数中的第一个参数);

image = picResource;

我的问题如下 - 如果我创建一个敌人对象列表(有很多敌人!),这会导致位图数据的重复吗?我不确定文档中它的低级实现是否会模拟C中的指针行为,因此只会以这种方式构造它的最小开销,或者我是否在咀嚼内存,因为我基本上复制了所有内容图片文件中的数据。

1 个答案:

答案 0 :(得分:1)

  

我创建了一个敌人对象列表(有很多敌人!),这会导致位图数据的重复吗?

每次调用decodeResource()都会导致新的内存中位图。如果您在问题中创建了所有敌人:

enemy = new Enemy(
    BitmapFactory.decodeResource(getResources(), R.drawable.enemy_pic)
);

每个Enemy对象都有自己独特的位图。

也就是说,如果你把它放在循环中

List<Enemy> enemies = new ArrayList<>();
for (int i = 0; i < nEnemies; ++i) {
   enemy = new Enemy(
       BitmapFactory.decodeResource(getResources(), R.drawable.enemy_pic)
   );
   enemies.add(enemy);
}

您将获得nEmemies个位图,即每个Enemy对象都有自己的(内存中)位图。

如果只解码敌人位图一次并将结果引用传递给Enemy构造函数,则只需创建对单个现有位图的新引用。也就是说,将上述内容重写为(例如)

List<Enemy> enemies = new ArrayList<>();
Bitmap enemyBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.enemy_pic);
for (int i = 0; i < nEnemies; ++i) {
   enemy = new Enemy(enemyBitmap);
   enemies.add(enemy);
}

只会导致所有敌人共享单个位图(除非Enemy对位图执行某些操作以创建副本)。

回头看你的答案。在Java中,表单的分配

image = picResource;

不创建副本,但只创建其他引用(确切地说,这仅适用于引用类型,即对象)。

附注:如果您使用Context.getDrawable(),则可以使用Android的可绘制缓存,即使重复调用也能获得相同的绘图。