1 package com.xtremelabs.robolectric.shadows; 2 3 import com.xtremelabs.robolectric.internal.Implementation; 4 import com.xtremelabs.robolectric.internal.Implements; 5 import com.xtremelabs.robolectric.internal.RealObject; 6 7 import android.os.HandlerThread; 8 import android.os.Looper; 9 10 import java.lang.reflect.InvocationTargetException; 11 import java.lang.reflect.Method; 12 13 @Implements(HandlerThread.class) 14 public class ShadowHandlerThread { 15 private Looper looper; 16 17 @RealObject 18 private HandlerThread thread; 19 __constructor__(String name)20 public void __constructor__(String name) { 21 __constructor__(name, -1); 22 } 23 24 @SuppressWarnings("UnusedParameters") __constructor__(String name, int priority)25 public void __constructor__(String name, int priority) { 26 } 27 28 @Implementation run()29 public void run() { 30 Looper.prepare(); 31 synchronized (this) { 32 looper = Looper.myLooper(); 33 onLooperPrepared(); 34 notifyAll(); 35 } 36 Looper.loop(); 37 } 38 39 @Implementation getLooper()40 public Looper getLooper() { 41 if (!thread.isAlive()) { 42 return null; 43 } 44 45 // If the thread has been started, wait until the looper has been created. 46 synchronized (this) { 47 while (thread.isAlive() && looper == null) { 48 try { 49 wait(); 50 } catch (InterruptedException ignored) { 51 } 52 } 53 } 54 return looper; 55 } 56 57 @Implementation quit()58 public boolean quit() { 59 Looper looper = getLooper(); 60 if (looper != null) { 61 looper.quit(); 62 return true; 63 } 64 return false; 65 } 66 67 @Implementation onLooperPrepared()68 public void onLooperPrepared() { 69 Method prepared; 70 try { 71 prepared = HandlerThread.class.getDeclaredMethod("onLooperPrepared"); 72 prepared.setAccessible(true); 73 prepared.invoke(thread); 74 } catch (NoSuchMethodException ignored) { 75 } catch (InvocationTargetException ignored) { 76 } catch (IllegalAccessException ignored) { 77 } 78 } 79 80 } 81