2016-02-25 14 views
9

Ich möchte einen Espresso-Matcher schreiben, der verifiziert, dass ein ImageView eine bestimmte Bitmap hat. Da die App Bilder über Glide lädt, dachte ich, dass ich das gleiche auf der Testseite tun muss, um das Beschneiden/Zentrieren zu berücksichtigen, bevor ich tatsächlich die erwarteten und tatsächlichen Bitmaps vergleichen kann.Bild wird synchron mit Glide geladen

Hier ist, was ich mit so weit kam:

BitmapRequestBuilder<Uri, Bitmap> bitmapRequest = Glide.with(imageView.getContext()) 
     .load(Uri.parse("file:///android_asset/" + mPath)) 
     .asBitmap(); 

switch (imageView.getScaleType()) { 
    case CENTER_CROP: 
     bitmapRequest.centerCrop(); 
     break; 
    case FIT_CENTER: 
    case FIT_START: 
    case FIT_END: 
     bitmapRequest.fitCenter(); 
     break; 
    default: 
     // no scaling applied to the ImageView under test 
} 

AtomicReference<Bitmap> bmRef = new AtomicReference<>(); 
bitmapRequest.into(new SimpleTarget<Bitmap>(
      imageView.getMeasuredWidth(), 
      imageView.getMeasuredHeight() 
) { 
    @Override 
    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { 
     bmRef.set(resource); 
    } 
}); 

// ??? 

try { 
    Bitmap expected = bmRef.get(); 
    return expected.sameAs(bitmap); 
} catch (Exception e) { 
    throw new IllegalStateException("could not load asset " + mPath, e); 
} 

Nun ist die Frage hier ist natürlich, dass ich einen Deadlock haben. Ich bin auf dem Hauptthread (der Matcher wird auf dem Hauptthread IIRC ausgeführt) und Glide möchte einen Backend-Thread, um die Bitmap zu laden und kehrt dann zum Hauptthread (in 'onResourceReady') zurück. Also muss ich von außen auf das Ergebnis warten, das auf der Innenseite steht, während der Haupt-Thread läuft.

I (erfolglos) versucht, den aktuellen Looper über Looper.loop() in // ??? und auch die regelmäßige Sperr-/Warte Ansatz, aber nichts funktionierte versucht vorzurücken. Ich bin aus Ideen ...

Antwort

-1

Für solche Fälle verwende ich eine einfache sleep, es ist nicht die beste Option, aber es funktioniert für mich.

public static void waitForActivity(long time) { 
    try { 
     Thread.sleep(time); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 
+0

Das in diesem Fall nicht funktioniert, leider habe gerade versucht es erneut. –

-1

Eine Möglichkeit, dies zu tun, um Ihre Vergleichslogik innerhalb onResourceReady zu halten, Und dann, wenn Sie irgendeine EventBus verwenden dann auslösen Ereignis mit dem Ergebnis und setzt UI-Logik in der Methode, die auf dieses Ereignis abonniert hat. Wenn kein Event-Bus verwendet wird, wird LocalBroadcastManager gesendet.

Zum Beispiel:

private BroadcastReceiver receiver; 

private void doWhateverYouWantWithResult(boolean result) { 

} 

bitmapRequest.into(new SimpleTarget<Bitmap>(
      imageView.getMeasuredWidth(), 
      imageView.getMeasuredHeight() 
) { 
    @Override 
    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { 
     bmRef.set(resource); 
     Bitmap expected = resource; 
     boolean result = expected.sameAs(bitmap); 
     Intent localIntent = 
       new Intent(BROADCAST_ACTION) 
         // Puts the status into the Intent 
         .putExtra(MATCH_RESULT, result); 
     // Broadcasts the Intent to receivers in this app. 
     LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent); 
    } 
}); 


    @Override 
    public void onResume(){ 
     super.onResume(); 
     receiver = new BroadcastReceiver() { 
      @Override 
      public void onReceive(Context context, Intent intent) { 
       boolean result = intent.getBooleanExtra(MATCH_RESULT); 
       doWhateverYouWantWithResult(result); 
      } 
     }; 
     LocalBroadcastManager.getInstance(getContext()) 
       .registerReceiver(receiver, new IntentFilter(BROADCAST_ACTION)); 
    } 

    @Override 
    public void onPause(){ 
     super.onPause(); 
     LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(receiver); 
    } 
Verwandte Themen