2016-03-25 26 views
2

Küçük bir uygulama oluşturdum (bir proje olarak, onu serbest bırakma planları olmadan). Kodun bir kısmı, rasgele sayılar içeren bir ızgara oluşturur ve söz konusu numaraya sahip bir listeden hareketli grafiği kullanarak bir ızgara görüntüler. En azından Kindle Fire'ımda (ve denediğim başka bir cihazda) beklendiği gibi davrandı.Emülatör neden cihazımdan daha az rastgele?

Ancak, emülatör farklı bir hikaye. Bence taklit edilen cihaz genel bir Samsung (4, belki de). Aynı kod, emülatörde çalıştırıldığında, bir sprite ile yaklaşık yarısı ve farklı bir hareketli grafiğin yarısını doldurur.

ızgara emülatörünüzde bu gibi görünebilir:

yerine gerçek cihazlarda bu
11177 
11177 
11777 
11777 
11777 

:

64251 
26253 
87635 
38415 
28167 

benim kod ilgili kısmı (evet, ben gerektiği hareket new Random() başka yerlerde):

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

I Geçmişte, Java'da, daha az rastgele olmaya karar veren Random ile ilgili sorunlar yaşadım (optimizasyondan kaynaklanabileceğine inanıyorum).

Emülatör neden daha az rastlantısal davranıyor? (Ve bunu nasıl düzeltebilirim?)

cevap

3

"Evet, new Random() başka bir yere gitmeliyim" ifadesinden şüphe ettiğinizi düşündüğünüzden daha kesin.

Android'in java.util.Random sınıfı için kaynağı bulabilirsiniz; Not kitkat ve lollipop/marshmallow sürümleri farklıdır.

kitkat:

public Random() { 
    // Note: Using identityHashCode() to be hermetic wrt subclasses. 
    setSeed(System.currentTimeMillis() + System.identityHashCode(this)); 
} 

hatmi:

public Random() { 
    // Note: Don't use identityHashCode(this) since that causes the monitor to 
    // get inflated when we synchronize. 
    setSeed(System.nanoTime() + seedBase); 
    ++seedBase; 
} 

Not nanosaniye-ayrıntı için zaman milisaniye-taneciklik arasındaki değişim. Bununla birlikte, bu değişiklik yalnızca, taklit edilen aygıtın aslında bu kadar ayrıntılı bir saati varsa geçerlidir. Bazı emülatörler çok kaba saatlere sahip olabilir, bu da System.nanoTime()'un makul bir hızlı döngünün her yinelemesinde aynı değeri döndürdüğü anlamına gelir.

Her döngüde yeni rasgele sayı üreteçleri oluşturuyorsunuz, bunları N, N + 1, N + 2 vb. Ile ekiyorsunuz. Tohumlar hemen hemen aynı olduğu için, ilk sayı çıktısındaki bitlerin çoğu aynıdır.

"Yeni Rastgele" yi döngüden çıkarırsanız, yalnızca daha verimli olmaz, aynı anda rastgele sayı üretecinin tam dizisi boyunca ilerlemesine ve daha iyi sonuçlar vermesine izin verir.

+0

Android, _own_ java.util.Random ??? – Laurel

+0

@Laurel bu yapıcı, jeneratörü uygulama değil. – pjs

+0

Şu anda 'N' sürümünün kaynaklarının bulunduğu "ana" dalın çok farklı bir uygulaması var: https://android.googlesource.com/platform/libcore/+/master/ojluni/src/main/ java/java/util/Random.java – fadden

İlgili konular