2016-02-25 17 views
9

Chcę napisać matę do espresso, która sprawdza, czy `ImageView' ma określony zestaw map bitowych. Ponieważ aplikacja ładuje obrazy za pośrednictwem Glide, pomyślałem, że muszę zrobić to samo po stronie testowej, aby obliczyć kadrowanie/centrowanie, zanim będę mógł porównać oczekiwane i rzeczywiste bitmapy.Ładowanie obrazu synchronicznie z Glide

Oto co wymyśliłem tej pory:

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

Teraz kwestią jest oczywiście, że mam impasu. Jestem w głównym wątku (Matcher jest wykonywany na głównym wątku IIRC), a Glide chce, aby wątek backendu wczytał bitmapę, a następnie powrócił na główny wątek (w samym "onResourceReady"). Muszę więc poczekać z zewnątrz na wynik, który jest zamieszczony wewnątrz, przy jednoczesnym zachowaniu głównego wątku.

Ja (bezskutecznie) próbowałem awansować bieżącego loopera przez Looper.loop() w // ???, a także wypróbowałem metodę regularnego blokowania/oczekiwania, ale nic nie działało. Nie mam pomysłów ...

Odpowiedz

-1

W takich przypadkach używam prostego sleep, nie jest to najlepsza opcja, ale działa dla mnie.

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

To nie działa w tym przypadku, niestety, tylko próbował go ponownie. –

-1

Jednym ze sposobów, aby to zrobić, aby utrzymać porównywania logiki wewnątrz onResourceReady, A jeśli używasz żadnego eventbus następnie wywołać zdarzenie z wyniku i umieścić logikę UI wewnątrz metody, które przystąpiło do tego wydarzenia. Jeśli nie korzystasz z żadnego autobusu zdarzeń, wówczas LocalBroadcastManager nadaje wynik.

Na przykład:

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); 
    } 
Powiązane problemy