问题描述
我创建了一个小应用程序(作为一个项目,没有计划发布它).部分代码生成一个随机数网格,并使用带有该数字的列表中的子画面显示一个网格.至少在我的Kindle Fire(以及我尝试过的另一台设备)上,它的表现均符合预期.
I created a small app (as a project, with no plans to release it). Part of the code generates a grid of random numbers and and displays a grid using the sprite from a list with said number. It behaved as expected, at least on my Kindle Fire (and another device I tried it on).
但是,仿真器则是另一回事.我认为仿真设备是通用的三星(也许是4个).在模拟器上运行时,相同的代码用一个精灵填充大约一半的网格,而用另一种精灵填充一半的网格.
The emulator, however, is a different story. I think the emulated device was a generic Samsung (4, maybe). The same code, when run on the emulator, fills about half the grid with one sprite, and half with a different sprite.
在模拟器上,网格可能看起来像这样:
The grid might look like this on the emulator:
11177
11177
11777
11777
11777
而不是在实际设备上:
64251
26253
87635
38415
28167
我代码的相关部分(是的,我应该将new Random()
移至其他位置)
The relevant part of my code (yes, I should move new Random()
elsewhere):
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
决定减少随机性(我相信这可能是由于优化).
I have had issues in the past, in Java, with Random
deciding to be less random (I believe it might be due to optimizations).
为什么模拟器的行为随机性较低? (以及如何解决?)
Why is the emulator behaving less randomly? (And how do I fix it?)
推荐答案
我怀疑您的是的,我应该将new Random()
移到其他地方"这句话比您想象的更准确.
I suspect your "yes, I should move new Random()
elsewhere" remark is more accurate than you think.
您可以找到Android的java.util.Random类的源代码;请注意 kitkat 和棒棒糖/棉花糖版本不同.
You can find the source for Android's java.util.Random class; note the kitkat and lollipop/marshmallow versions are different.
奇巧:
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()
可能会在相当快的循环的每次迭代中返回相同的值.
Note the change from millisecond-granularity time to nanosecond-granularity time. However, this change is only relevant if the emulated device actually has a clock that granular. Some emulators may have very coarse clocks, which means that System.nanoTime()
could be returning the same value on every iteration of a reasonably fast loop.
您将在每个循环中创建新的随机数生成器,并为它们添加N,N + 1,N + 2等.因为种子几乎相同,所以第一个数字输出中的大多数位都是相同的.
You're creating new random number generators each loop, seeding them with N, N+1, N+2, and so on. Because the seeds are nearly identical, most of the bits in the first number output are identical.
如果您将新的随机数"从循环中拉出来,不仅效率更高,还将使伪随机数生成器逐步完成其全部序列,并为您提供更好的结果.
If you pull the "new Random" out of the loop, not only will it be more efficient, it will allow the pseudo-random number generator to progress through its full sequence and give you better results.
这篇关于为什么模拟器的随机性比我的设备低?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!