Skip to content

Commit 8291488

Browse files
committed
Implemented @UiThread with CodeModelé
1 parent d5b5256 commit 8291488

3 files changed

Lines changed: 143 additions & 88 deletions

File tree

‎AndroidAnnotations/src/main/java/com/googlecode/androidannotations/generation/BackgroundInstruction.java‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ public BackgroundInstruction(String className, String methodName, List<String> m
4848
this.methodName = methodName;
4949
this.methodArguments = methodArguments;
5050
this.methodParameters = methodParameters;
51-
5251
addImports("android.util.Log");
5352
}
5453

‎AndroidAnnotations/src/main/java/com/googlecode/androidannotations/generation/UiThreadInstruction.java‎

Lines changed: 50 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -19,64 +19,63 @@
1919

2020
public class UiThreadInstruction extends AbstractInstruction {
2121

22-
private static final String FORMAT = //
23-
"" + //
24-
" @Override\n" + //
25-
" public void %s(%s) {\n" + //
26-
" runOnUiThread(new Runnable() {\n" + //
27-
" public void run() {\n" + //
28-
" try {\n" + //
29-
" %s.super.%s(%s);\n" + //
30-
" } catch (RuntimeException e) {\n" + //
31-
" Log.e(\"%s\", \"A runtime exception was thrown while executing code in the ui thread\", e);\n" + //
32-
" }\n" + //
33-
" }\n" + //
34-
" });\n" + //
35-
" }\n" + //
36-
"\n";
22+
private static final String FORMAT = //
23+
"" + //
24+
" @Override\n" + //
25+
" public void %s(%s) {\n" + //
26+
" runOnUiThread(new Runnable() {\n" + //
27+
" public void run() {\n" + //
28+
" try {\n" + //
29+
" %s.super.%s(%s);\n" + //
30+
" } catch (RuntimeException e) {\n" + //
31+
" Log.e(\"%s\", \"A runtime exception was thrown while executing code in the ui thread\", e);\n" + //
32+
" }\n" + //
33+
" }\n" + //
34+
" });\n" + //
35+
" }\n" + //
36+
"\n";
3737

38-
private final String methodName;
38+
private final String methodName;
3939

40-
private final String className;
40+
private final String className;
4141

42-
private final List<String> methodArguments;
42+
private final List<String> methodArguments;
4343

44-
private final List<String> methodParameters;
44+
private final List<String> methodParameters;
4545

46-
public UiThreadInstruction(String className, String methodName, List<String> methodArguments, List<String> methodParameters) {
47-
this.className = className;
48-
this.methodName = methodName;
49-
this.methodArguments = methodArguments;
50-
this.methodParameters = methodParameters;
51-
addImports("android.util.Log");
52-
}
46+
public UiThreadInstruction(String className, String methodName, List<String> methodArguments, List<String> methodParameters) {
47+
this.className = className;
48+
this.methodName = methodName;
49+
this.methodArguments = methodArguments;
50+
this.methodParameters = methodParameters;
51+
addImports("android.util.Log");
52+
}
5353

54-
@Override
55-
public String generate() {
54+
@Override
55+
public String generate() {
56+
StringBuilder arguments = new StringBuilder();
57+
boolean first = true;
58+
for (String argument : methodArguments) {
59+
if (first) {
60+
first = false;
61+
} else {
62+
arguments.append(", ");
63+
}
64+
arguments.append("final ").append(argument);
65+
}
5666

57-
StringBuilder arguments = new StringBuilder();
58-
boolean first = true;
59-
for(String argument : methodArguments) {
60-
if (first) {
61-
first = false;
62-
} else {
63-
arguments.append(", ");
64-
}
65-
arguments.append("final ").append(argument);
66-
}
67-
68-
first = true;
69-
StringBuilder parameters = new StringBuilder();
70-
for(String parameter : methodParameters) {
71-
if (first) {
72-
first = false;
73-
} else {
74-
parameters.append(", ");
75-
}
76-
parameters.append(parameter);
77-
}
67+
first = true;
68+
StringBuilder parameters = new StringBuilder();
69+
for (String parameter : methodParameters) {
70+
if (first) {
71+
first = false;
72+
} else {
73+
parameters.append(", ");
74+
}
75+
parameters.append(parameter);
76+
}
7877

79-
return String.format(FORMAT, methodName, arguments.toString(), className, methodName, parameters.toString(), className);
80-
}
78+
return String.format(FORMAT, methodName, arguments.toString(), className, methodName, parameters.toString(), className);
79+
}
8180

8281
}

‎AndroidAnnotations/src/main/java/com/googlecode/androidannotations/processing/UiThreadProcessor.java‎

Lines changed: 93 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,45 +28,102 @@
2828
import com.googlecode.androidannotations.model.Instruction;
2929
import com.googlecode.androidannotations.model.MetaActivity;
3030
import com.googlecode.androidannotations.model.MetaModel;
31+
import com.sun.codemodel.JBlock;
32+
import com.sun.codemodel.JCatchBlock;
33+
import com.sun.codemodel.JClass;
34+
import com.sun.codemodel.JClassAlreadyExistsException;
3135
import com.sun.codemodel.JCodeModel;
36+
import com.sun.codemodel.JDefinedClass;
37+
import com.sun.codemodel.JExpr;
38+
import com.sun.codemodel.JExpression;
39+
import com.sun.codemodel.JInvocation;
40+
import com.sun.codemodel.JMethod;
41+
import com.sun.codemodel.JMod;
42+
import com.sun.codemodel.JTryBlock;
43+
import com.sun.codemodel.JVar;
3244

3345
public class UiThreadProcessor implements ElementProcessor {
3446

35-
@Override
36-
public Class<? extends Annotation> getTarget() {
37-
return UiThread.class;
38-
}
39-
40-
@Override
41-
public void process(Element element, MetaModel metaModel) {
42-
43-
String methodName = element.getSimpleName().toString();
44-
45-
Element enclosingElement = element.getEnclosingElement();
46-
MetaActivity metaActivity = metaModel.getMetaActivities().get(enclosingElement);
47-
String className = metaActivity.getClassSimpleName();
48-
List<Instruction> memberInstructions = metaActivity.getMemberInstructions();
49-
50-
List<String> methodArguments = new ArrayList<String>();
51-
List<String> methodParameters = new ArrayList<String>();
52-
53-
ExecutableElement executableElement = (ExecutableElement) element;
54-
55-
for(VariableElement parameter : executableElement.getParameters()) {
56-
String parameterName = parameter.getSimpleName().toString();
57-
String parameterType = parameter.asType().toString();
58-
methodArguments.add(parameterType+" "+parameterName);
59-
methodParameters.add(parameterName);
60-
}
61-
62-
Instruction instruction = new UiThreadInstruction(className, methodName, methodArguments, methodParameters);
63-
memberInstructions.add(instruction);
64-
}
65-
66-
@Override
67-
public void process(Element element, JCodeModel codeModel, ActivitiesHolder activitiesHolder) {
68-
// TODO Auto-generated method stub
69-
70-
}
47+
@Override
48+
public Class<? extends Annotation> getTarget() {
49+
return UiThread.class;
50+
}
51+
52+
@Override
53+
public void process(Element element, MetaModel metaModel) {
54+
55+
String methodName = element.getSimpleName().toString();
56+
57+
Element enclosingElement = element.getEnclosingElement();
58+
MetaActivity metaActivity = metaModel.getMetaActivities().get(enclosingElement);
59+
String className = metaActivity.getClassSimpleName();
60+
List<Instruction> memberInstructions = metaActivity.getMemberInstructions();
61+
62+
List<String> methodArguments = new ArrayList<String>();
63+
List<String> methodParameters = new ArrayList<String>();
64+
65+
ExecutableElement executableElement = (ExecutableElement) element;
66+
67+
for (VariableElement parameter : executableElement.getParameters()) {
68+
String parameterName = parameter.getSimpleName().toString();
69+
String parameterType = parameter.asType().toString();
70+
methodArguments.add(parameterType + " " + parameterName);
71+
methodParameters.add(parameterName);
72+
}
73+
74+
Instruction instruction = new UiThreadInstruction(className, methodName, methodArguments, methodParameters);
75+
memberInstructions.add(instruction);
76+
}
77+
78+
@Override
79+
public void process(Element element, JCodeModel codeModel, ActivitiesHolder activitiesHolder) throws JClassAlreadyExistsException {
80+
81+
ActivityHolder holder = activitiesHolder.getActivityHolder(element);
82+
83+
// Method
84+
String backgroundMethodName = element.getSimpleName().toString();
85+
JMethod method = holder.activity.method(JMod.PUBLIC, codeModel.VOID, backgroundMethodName);
86+
method.annotate(Override.class);
87+
88+
// Method parameters
89+
List<JVar> parameters = new ArrayList<JVar>();
90+
ExecutableElement executableElement = (ExecutableElement) element;
91+
for (VariableElement parameter : executableElement.getParameters()) {
92+
String parameterName = parameter.getSimpleName().toString();
93+
JClass parameterClass = holder.refClass(parameter.asType().toString());
94+
JVar param = method.param(JMod.FINAL, parameterClass, parameterName);
95+
parameters.add(param);
96+
}
97+
98+
JDefinedClass anonymousRunnableClass = codeModel.anonymousClass(Runnable.class);
99+
100+
JMethod runMethod = anonymousRunnableClass.method(JMod.PUBLIC, codeModel.VOID, "run");
101+
runMethod.annotate(Override.class);
102+
103+
JBlock runMethodBody = runMethod.body();
104+
JTryBlock runTry = runMethodBody._try();
105+
106+
JExpression activitySuper = holder.activity.staticRef("super");
107+
108+
JInvocation superCall = runTry.body().invoke(activitySuper, method);
109+
for (JVar param : parameters) {
110+
superCall.arg(param);
111+
}
112+
JCatchBlock runCatch = runTry._catch(holder.refClass(RuntimeException.class));
113+
JVar exceptionParam = runCatch.param("e");
114+
115+
JClass logClass = holder.refClass("android.util.Log");
116+
117+
JInvocation errorInvoke = logClass.staticInvoke("e");
118+
119+
errorInvoke.arg(holder.activity.name());
120+
errorInvoke.arg("A runtime exception was thrown while executing code in the ui thread");
121+
errorInvoke.arg(exceptionParam);
122+
123+
runCatch.body().add(errorInvoke);
124+
125+
method.body().invoke("runOnUiThread").arg(JExpr._new(anonymousRunnableClass));
126+
127+
}
71128

72129
}

0 commit comments

Comments
 (0)