我创建了一个小应用程序(作为一个项目,没有计划发布它)。部分代码生成随机数网格,并使用具有所述数字的列表中的精灵显示网格。它的表现如预期,至少在我的Kindle Fire上(以及我尝试过的其他设备)。
然而,模拟器是一个不同的故事。我认为模拟设备是通用的三星(4,也许)。当在模拟器上运行时,相同的代码用一个精灵填充大约一半的网格,用一个不同的精灵填充一半。
网格在模拟器上看起来像这样:
.find()
而不是在真实设备上:
11177
11177
11777
11777
11777
我的代码的相关部分(是的,我应该在其他地方移动64251
26253
87635
38415
28167
):
new Random()
过去我在Java中遇到过问题,import java.util.Random;
// ... ... ...
for (int i = 0; i < GRID; i++) {
for (int j = 0; j < GRID; j++) {
paint.setColor(Color.parseColor("#FBB117"));
Random rand=new Random();
int num=rand.nextInt(8);
canvas.drawBitmap(bmp,frames[num],calcGridSpot(i,j),
paint);
//... Eventually closing braces:
}
}
决定随机性降低(我相信这可能是由于优化)。
为什么模拟器的行为随机性较小? (我该如何解决?)
答案 0 :(得分:3)
我怀疑你的#34;是的,我应该new Random()
移动到其他地方&#34;评论比你想象的更准确。
您可以找到Android的java.util.Random类的源代码;请注意,kitkat和lollipop/marshmallow版本不同。
奇巧:
public Random() {
// Note: Using identityHashCode() to be hermetic wrt subclasses.
setSeed(System.currentTimeMillis() + System.identityHashCode(this));
}
棉花糖:
public Random() {
// Note: Don't use identityHashCode(this) since that causes the monitor to
// get inflated when we synchronize.
setSeed(System.nanoTime() + seedBase);
++seedBase;
}
请注意从毫秒级粒度时间到纳秒级粒度时间的变化。但是,只有当仿真设备实际上具有粒度时钟时,此更改才有意义。某些仿真器可能具有非常粗略的时钟,这意味着System.nanoTime()
可以在相当快速的循环的每次迭代中返回相同的值。
您正在为每个循环创建新的随机数生成器,使用N,N + 1,N + 2等进行播种。由于种子几乎相同,因此第一个数字输出中的大多数位是相同的。
如果你拉出&#34;新的随机&#34;在循环之外,它不仅会更有效,它还允许伪随机数生成器在整个序列中前进并为您提供更好的结果。