2222import javax .lang .model .element .ExecutableElement ;
2323
2424import org .androidannotations .annotations .UiThread ;
25+ import org .androidannotations .annotations .UiThread .Propagation ;
2526import org .androidannotations .helper .APTCodeModelHelper ;
2627
28+ import android .os .Looper ;
29+
30+ import com .sun .codemodel .JBlock ;
2731import com .sun .codemodel .JClass ;
2832import com .sun .codemodel .JClassAlreadyExistsException ;
2933import com .sun .codemodel .JCodeModel ;
34+ import com .sun .codemodel .JConditional ;
3035import com .sun .codemodel .JDefinedClass ;
3136import com .sun .codemodel .JExpr ;
37+ import com .sun .codemodel .JExpression ;
3238import com .sun .codemodel .JMethod ;
3339import com .sun .codemodel .JMod ;
40+ import com .sun .codemodel .JOp ;
3441
3542public class UiThreadProcessor implements DecoratingElementProcessor {
3643
44+ private static final String METHOD_CUR_THREAD = "currentThread" ;
45+ private static final String METHOD_MAIN_LOOPER = "getMainLooper" ;
46+ private static final String METHOD_GET_THREAD = "getThread" ;
47+
3748 private final APTCodeModelHelper helper = new APTCodeModelHelper ();
3849
3950 @ Override
@@ -45,15 +56,15 @@ public String getTarget() {
4556 public void process (Element element , JCodeModel codeModel , EBeanHolder holder ) throws JClassAlreadyExistsException {
4657
4758 ExecutableElement executableElement = (ExecutableElement ) element ;
59+ UiThread annotation = element .getAnnotation (UiThread .class );
60+ Propagation propagation = annotation .propagation ();
4861
4962 JMethod delegatingMethod = helper .overrideAnnotatedMethod (executableElement , holder );
5063
5164 JDefinedClass anonymousRunnableClass = helper .createDelegatingAnonymousRunnableClass (holder , delegatingMethod );
5265
5366 {
5467 // Execute Runnable
55-
56- UiThread annotation = element .getAnnotation (UiThread .class );
5768 long delay = annotation .delay ();
5869
5970 if (holder .handler == null ) {
@@ -62,6 +73,11 @@ public void process(Element element, JCodeModel codeModel, EBeanHolder holder) t
6273 }
6374
6475 if (delay == 0 ) {
76+ if (propagation == Propagation .REUSE ) {
77+ // Put in the check for the UI thread.
78+ addUIThreadCheck (delegatingMethod , codeModel , holder );
79+ }
80+
6581 delegatingMethod .body ().invoke (holder .handler , "post" ).arg (_new (anonymousRunnableClass ));
6682 } else {
6783 delegatingMethod .body ().invoke (holder .handler , "postDelayed" ).arg (_new (anonymousRunnableClass )).arg (lit (delay ));
@@ -70,4 +86,29 @@ public void process(Element element, JCodeModel codeModel, EBeanHolder holder) t
7086
7187 }
7288
89+ /**
90+ * Add the pre-check to see if we are already in the UI thread.
91+ *
92+ * @param delegatingMethod
93+ * @param codeModel
94+ * @param holder
95+ * @throws JClassAlreadyExistsException
96+ */
97+ private void addUIThreadCheck (JMethod delegatingMethod , JCodeModel codeModel , EBeanHolder holder ) throws JClassAlreadyExistsException {
98+ // Get the Thread and Looper class.
99+ JClass tClass = codeModel .ref (Thread .class );
100+ JClass lClass = codeModel .ref (Looper .class );
101+
102+ // invoke the methods.
103+ JExpression lhs = tClass .staticInvoke (METHOD_CUR_THREAD );
104+ JExpression rhs = lClass .staticInvoke (METHOD_MAIN_LOOPER ).invoke (METHOD_GET_THREAD );
105+
106+ // create the conditional and the block.
107+ JConditional con = delegatingMethod .body ()._if (JOp .eq (lhs , rhs ));
108+ JBlock thenBlock = con ._then ();
109+
110+ helper .callSuperMethod (delegatingMethod , holder , thenBlock );
111+
112+ thenBlock ._return ();
113+ }
73114}
0 commit comments