3737import com .sun .codemodel .JMethod ;
3838import com .sun .codemodel .JMod ;
3939import com .sun .codemodel .JOp ;
40+ import com .sun .codemodel .JStatement ;
4041
4142public class UiThreadProcessor implements DecoratingElementProcessor {
4243
@@ -58,11 +59,14 @@ public void process(Element element, JCodeModel codeModel, EBeanHolder holder) t
5859
5960 JMethod delegatingMethod = helper .overrideAnnotatedMethod (executableElement , holder );
6061
62+ //Need to clone the body to be put in the check. This is done here because the next line
63+ //will remove the body from the method.
64+ JBlock clonedBody = cloneMethodBody (delegatingMethod );
65+
6166 JDefinedClass anonymousRunnableClass = helper .createDelegatingAnonymousRunnableClass (holder , delegatingMethod );
6267
6368 {
64- // Execute Runnable
65-
69+ //Execute Runnable
6670 UiThread annotation = element .getAnnotation (UiThread .class );
6771 long delay = annotation .delay ();
6872
@@ -71,7 +75,8 @@ public void process(Element element, JCodeModel codeModel, EBeanHolder holder) t
7175 holder .handler = holder .generatedClass .field (JMod .PRIVATE , handlerClass , "handler_" , JExpr ._new (handlerClass ));
7276 }
7377
74- addUIThreadCheck (delegatingMethod , codeModel );
78+ //Put in the check for the UI thread.
79+ addUIThreadCheck (delegatingMethod , clonedBody , codeModel );
7580
7681 if (delay == 0 ) {
7782 delegatingMethod .body ().invoke (holder .handler , "post" ).arg (_new (anonymousRunnableClass ));
@@ -82,26 +87,48 @@ public void process(Element element, JCodeModel codeModel, EBeanHolder holder) t
8287
8388 }
8489
90+ /**
91+ * Clone a method body.
92+ *
93+ * @param method the method to clone.
94+ * @return A new JBlock containing the method body.
95+ */
96+ private JBlock cloneMethodBody (JMethod method ) {
97+ JBlock clonedBody = new JBlock (false , false );
98+
99+ for (Object statement : method .body ().getContents ()) {
100+ clonedBody .add ((JStatement ) statement );
101+ }
102+
103+ return clonedBody ;
104+ }
105+
85106 /**
86107 * Add the pre-check to see if we are already in the UI thread.
87- *
108+ *
88109 * @param delegatingMethod
89110 * @param codeModel
90111 * @throws JClassAlreadyExistsException
91112 */
92- private void addUIThreadCheck (JMethod delegatingMethod , JCodeModel codeModel ) throws JClassAlreadyExistsException {
93- // Get the Thread and Looper class.
113+ private void addUIThreadCheck (JMethod delegatingMethod , JBlock clonedBody , JCodeModel codeModel ) throws JClassAlreadyExistsException {
114+ //Get the Thread and Looper class.
94115 JClass tClass = codeModel .ref (Thread .class );
95116 JClass lClass = codeModel .ref (Looper .class );
96117
97- // invoke the methods.
118+ //invoke the methods.
98119 JExpression lhs = tClass .staticInvoke (METHOD_CUR_THREAD );
99120 JExpression rhs = lClass .staticInvoke (METHOD_MAIN_LOOPER ).invoke (METHOD_GET_THREAD );
100121
101- // create the conditional and the block.
122+ //create the conditional and the block.
102123 JConditional con = delegatingMethod .body ()._if (JOp .eq (lhs , rhs ));
103124 JBlock block = con ._then ();
104- block .add (JExpr ._super ().invoke (delegatingMethod ));
125+
126+ //Put the cloned method body in the if() block, this is necessary because the
127+ //method may have parameters and a simple super.methodCall() won't work.
128+ for (Object statement : clonedBody .getContents ()) {
129+ block .add ((JStatement ) statement );
130+ }
131+
105132 block ._return ();
106133 }
107134}
0 commit comments