|
29 | 29 | import com.googlecode.androidannotations.model.Instruction; |
30 | 30 | import com.googlecode.androidannotations.model.MetaActivity; |
31 | 31 | import com.googlecode.androidannotations.model.MetaModel; |
| 32 | +import com.sun.codemodel.JBlock; |
| 33 | +import com.sun.codemodel.JCatchBlock; |
| 34 | +import com.sun.codemodel.JClass; |
| 35 | +import com.sun.codemodel.JClassAlreadyExistsException; |
32 | 36 | import com.sun.codemodel.JCodeModel; |
| 37 | +import com.sun.codemodel.JDefinedClass; |
| 38 | +import com.sun.codemodel.JExpr; |
| 39 | +import com.sun.codemodel.JExpression; |
| 40 | +import com.sun.codemodel.JInvocation; |
| 41 | +import com.sun.codemodel.JMethod; |
| 42 | +import com.sun.codemodel.JMod; |
| 43 | +import com.sun.codemodel.JTryBlock; |
| 44 | +import com.sun.codemodel.JVar; |
33 | 45 |
|
34 | 46 | public class UiThreadDelayedProcessor implements ElementProcessor { |
35 | 47 |
|
36 | | - @Override |
37 | | - public Class<? extends Annotation> getTarget() { |
38 | | - return UiThreadDelayed.class; |
39 | | - } |
| 48 | + @Override |
| 49 | + public Class<? extends Annotation> getTarget() { |
| 50 | + return UiThreadDelayed.class; |
| 51 | + } |
40 | 52 |
|
41 | | - @Override |
42 | | - public void process(Element element, MetaModel metaModel) { |
| 53 | + @Override |
| 54 | + public void process(Element element, MetaModel metaModel) { |
43 | 55 |
|
44 | | - String methodName = element.getSimpleName().toString(); |
| 56 | + String methodName = element.getSimpleName().toString(); |
45 | 57 |
|
46 | | - Element enclosingElement = element.getEnclosingElement(); |
47 | | - MetaActivity metaActivity = metaModel.getMetaActivities().get(enclosingElement); |
48 | | - String className = metaActivity.getClassSimpleName(); |
49 | | - List<Instruction> memberInstructions = metaActivity.getMemberInstructions(); |
| 58 | + Element enclosingElement = element.getEnclosingElement(); |
| 59 | + MetaActivity metaActivity = metaModel.getMetaActivities().get(enclosingElement); |
| 60 | + String className = metaActivity.getClassSimpleName(); |
| 61 | + List<Instruction> memberInstructions = metaActivity.getMemberInstructions(); |
50 | 62 |
|
51 | | - List<String> methodArguments = new ArrayList<String>(); |
52 | | - List<String> methodParameters = new ArrayList<String>(); |
| 63 | + List<String> methodArguments = new ArrayList<String>(); |
| 64 | + List<String> methodParameters = new ArrayList<String>(); |
53 | 65 |
|
54 | | - ExecutableElement executableElement = (ExecutableElement) element; |
| 66 | + ExecutableElement executableElement = (ExecutableElement) element; |
55 | 67 |
|
56 | | - for (VariableElement parameter : executableElement.getParameters()) { |
57 | | - String parameterName = parameter.getSimpleName().toString(); |
58 | | - String parameterType = parameter.asType().toString(); |
59 | | - methodArguments.add(parameterType + " " + parameterName); |
60 | | - methodParameters.add(parameterName); |
61 | | - } |
| 68 | + for (VariableElement parameter : executableElement.getParameters()) { |
| 69 | + String parameterName = parameter.getSimpleName().toString(); |
| 70 | + String parameterType = parameter.asType().toString(); |
| 71 | + methodArguments.add(parameterType + " " + parameterName); |
| 72 | + methodParameters.add(parameterName); |
| 73 | + } |
62 | 74 |
|
63 | | - UiThreadDelayed annotation = element.getAnnotation(UiThreadDelayed.class); |
64 | | - long delay = annotation.value(); |
| 75 | + UiThreadDelayed annotation = element.getAnnotation(UiThreadDelayed.class); |
| 76 | + long delay = annotation.value(); |
65 | 77 |
|
66 | | - Instruction instruction = new UiThreadDelayedInstruction(methodName, className, methodArguments, methodParameters, delay); |
67 | | - memberInstructions.add(instruction); |
| 78 | + Instruction instruction = new UiThreadDelayedInstruction(methodName, className, methodArguments, methodParameters, delay); |
| 79 | + memberInstructions.add(instruction); |
68 | 80 |
|
69 | | - Instruction handlerInstruction = new HandlerInstruction(); |
70 | | - if (!memberInstructions.contains(handlerInstruction)) { |
71 | | - memberInstructions.add(handlerInstruction); |
72 | | - } |
73 | | - } |
| 81 | + Instruction handlerInstruction = new HandlerInstruction(); |
| 82 | + if (!memberInstructions.contains(handlerInstruction)) { |
| 83 | + memberInstructions.add(handlerInstruction); |
| 84 | + } |
| 85 | + } |
74 | 86 |
|
75 | | - @Override |
76 | | - public void process(Element element, JCodeModel codeModel, ActivitiesHolder activitiesHolder) { |
77 | | - // TODO Auto-generated method stub |
78 | | - |
79 | | - } |
| 87 | + @Override |
| 88 | + public void process(Element element, JCodeModel codeModel, ActivitiesHolder activitiesHolder) throws JClassAlreadyExistsException { |
| 89 | + |
| 90 | + ActivityHolder holder = activitiesHolder.getActivityHolder(element); |
| 91 | + |
| 92 | + // Method |
| 93 | + String backgroundMethodName = element.getSimpleName().toString(); |
| 94 | + JMethod method = holder.activity.method(JMod.PUBLIC, codeModel.VOID, backgroundMethodName); |
| 95 | + method.annotate(Override.class); |
| 96 | + |
| 97 | + // Method parameters |
| 98 | + List<JVar> parameters = new ArrayList<JVar>(); |
| 99 | + ExecutableElement executableElement = (ExecutableElement) element; |
| 100 | + for (VariableElement parameter : executableElement.getParameters()) { |
| 101 | + String parameterName = parameter.getSimpleName().toString(); |
| 102 | + JClass parameterClass = holder.refClass(parameter.asType().toString()); |
| 103 | + JVar param = method.param(JMod.FINAL, parameterClass, parameterName); |
| 104 | + parameters.add(param); |
| 105 | + } |
| 106 | + |
| 107 | + JDefinedClass anonymousRunnableClass = codeModel.anonymousClass(Runnable.class); |
| 108 | + |
| 109 | + JMethod runMethod = anonymousRunnableClass.method(JMod.PUBLIC, codeModel.VOID, "run"); |
| 110 | + runMethod.annotate(Override.class); |
| 111 | + |
| 112 | + JBlock runMethodBody = runMethod.body(); |
| 113 | + JTryBlock runTry = runMethodBody._try(); |
| 114 | + |
| 115 | + JExpression activitySuper = holder.activity.staticRef("super"); |
| 116 | + |
| 117 | + JInvocation superCall = runTry.body().invoke(activitySuper, method); |
| 118 | + for (JVar param : parameters) { |
| 119 | + superCall.arg(param); |
| 120 | + } |
| 121 | + JCatchBlock runCatch = runTry._catch(holder.refClass(RuntimeException.class)); |
| 122 | + JVar exceptionParam = runCatch.param("e"); |
| 123 | + |
| 124 | + JClass logClass = holder.refClass("android.util.Log"); |
| 125 | + |
| 126 | + JInvocation errorInvoke = logClass.staticInvoke("e"); |
| 127 | + |
| 128 | + errorInvoke.arg(holder.activity.name()); |
| 129 | + errorInvoke.arg("A runtime exception was thrown while executing code in the ui thread"); |
| 130 | + errorInvoke.arg(exceptionParam); |
| 131 | + |
| 132 | + runCatch.body().add(errorInvoke); |
| 133 | + |
| 134 | + UiThreadDelayed annotation = element.getAnnotation(UiThreadDelayed.class); |
| 135 | + long delay = annotation.value(); |
| 136 | + |
| 137 | + if (holder.handler == null) { |
| 138 | + JClass handlerClass = holder.refClass("android.os.Handler"); |
| 139 | + holder.handler = holder.activity.field(JMod.PRIVATE, handlerClass, "handler_", JExpr._new(handlerClass)); |
| 140 | + } |
| 141 | + |
| 142 | + method.body().invoke(holder.handler, "postDelayed").arg(JExpr._new(anonymousRunnableClass)).arg(JExpr.lit(delay)); |
| 143 | + |
| 144 | + } |
80 | 145 |
|
81 | 146 | } |
0 commit comments