2016-02-25 16 views
9

Desidero scrivere un controllo Espresso che verifichi che un 'ImageView' abbia un set di bitmap specifico. Poiché l'app esegue il caricamento delle immagini tramite Glide, ho pensato di dover fare lo stesso sul lato del test per tenere conto del ritaglio/centraggio prima di poter effettivamente confrontare le bitmap previste e quelle effettive.Caricamento immagine sincrono con Glide

Ecco quello che mi è venuto in mente finora:

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); 
} 

Ora il problema qui è, naturalmente, che ho una situazione di stallo. Sono sul thread principale (il matcher è eseguito sul thread principale IIRC) e Glide vuole un thread di backend per caricare la bitmap e quindi ritorna sul thread principale (in 'onResourceReady') stesso. Quindi ho bisogno di aspettare dall'esterno per il risultato che viene pubblicato all'interno, mantenendo il thread principale in esecuzione.

I (senza successo) ha tentato di far avanzare il looper corrente tramite Looper.loop() in // ??? e ha anche provato il normale approccio lock/wait, ma non ha funzionato. Sono fuori di idee ...

risposta

-1

Per casi come quello io uso un semplice sleep, non è l'opzione migliore, ma funziona per me.

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

Questo non funziona in questo caso, purtroppo, appena provato di nuovo. –

-1

Un modo per fare questo per mantenere la logica di confronto all'interno onResourceReady, E poi se si utilizza qualsiasi EventBus poi Trigger Event con il risultato e mettere la logica dell'interfaccia utente all'interno del metodo, che aderisce a questo evento. Se non si utilizza alcun bus eventi, immettere LocalBroadcastManager per trasmettere il risultato.

Ad esempio:

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); 
    }