android 为什么模拟器比我的设备随机性低?

wyyhbhjk  于 2023-06-04  发布在  Android
关注(0)|答案(1)|浏览(331)

我创建了一个小应用程序(作为一个项目,没有计划发布它)。代码的一部分生成一个随机数字网格,并使用带有所述数字的列表中的精灵显示网格。它的表现和预期的一样,至少在我的Kindle Fire上(还有我试用的另一款设备)。
然而,模拟器是一个不同的故事。我认为模拟设备是一个通用的三星(4,也许)。当在模拟器上运行相同的代码时,用一个精灵填充大约一半的网格,用另一个精灵填充另一半。
在模拟器上,网格可能看起来像这样:

11177
11177
11777
11777
11777

而不是在真实的设备上:

64251
26253
87635
38415
28167

我的代码的相关部分(是的,我应该将new Random()移到其他地方):

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:
      }
 }

我在过去遇到过问题,在Java中,Random决定不那么随机(我相信这可能是由于优化)。
为什么模拟器的行为不那么随机?(我该如何修复它?)

isr3a4wc

isr3a4wc1#

我怀疑你的“是的,我应该把new Random()移到其他地方”的评论比你想象的更准确。
您可以找到Android的java.util.Random类的源代码;注意kitkatlollipop/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等作为种子。因为种子几乎相同,所以第一个数字输出中的大多数位是相同的。
如果你把“新随机”从循环中拉出来,它不仅会更有效率,而且会允许伪随机数生成器在其完整序列中前进,并给予你更好的结果。

相关问题