请原谅我可能是一个非常令人难以置信的问题(我对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中的指针行为,因此只会以这种方式构造它的最小开销,或者我是否在咀嚼内存,因为我基本上复制了所有内容图片文件中的数据。
答案 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的可绘制缓存,即使重复调用也能获得相同的绘图。