Skip to content

Commit c11e74f

Browse files
committed
Refactor Intent builders
1 parent c0373fc commit c11e74f

10 files changed

Lines changed: 363 additions & 210 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package org.androidannotations.api.builder;
2+
3+
import android.app.Activity;
4+
import android.content.Context;
5+
6+
public class ActivityIntentBuilder<I extends ActivityIntentBuilder<I>> extends IntentBuilder<I> {
7+
8+
public ActivityIntentBuilder(Context context, Class<?> clazz) {
9+
super(context, clazz);
10+
}
11+
12+
public void start() {
13+
context.startActivity(intent);
14+
}
15+
16+
public void startForResult(int requestCode) {
17+
if (context instanceof Activity) {
18+
((Activity) context).startActivityForResult(intent, requestCode);
19+
} else {
20+
context.startActivity(intent);
21+
}
22+
}
23+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package org.androidannotations.api.builder;
2+
3+
public class Builder {
4+
}
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package org.androidannotations.api.builder;
2+
3+
import android.content.Context;
4+
import android.content.Intent;
5+
import android.os.Bundle;
6+
import android.os.Parcelable;
7+
8+
import java.io.Serializable;
9+
import java.util.ArrayList;
10+
11+
@SuppressWarnings("unchecked")
12+
public class IntentBuilder<I extends IntentBuilder<I>> extends Builder {
13+
14+
protected final Context context;
15+
protected final Intent intent;
16+
17+
public IntentBuilder(Context context, Class<?> clazz) {
18+
this.context = context;
19+
intent = new Intent(context, clazz);
20+
}
21+
22+
public IntentBuilder(Context context, Intent intent) {
23+
this.context = context;
24+
this.intent = intent;
25+
}
26+
27+
public Context getContext() {
28+
return context;
29+
}
30+
31+
public Intent get() {
32+
return intent;
33+
}
34+
35+
public I flags(int flags) {
36+
intent.setFlags(flags);
37+
return (I) this;
38+
}
39+
40+
public I extras(Bundle bundle) {
41+
intent.putExtras(bundle);
42+
return (I) this;
43+
}
44+
45+
public I putExtra(String name, boolean value) {
46+
intent.putExtra(name, value);
47+
return (I) this;
48+
}
49+
50+
public I putExtra(String name, byte value) {
51+
intent.putExtra(name, value);
52+
return (I) this;
53+
}
54+
55+
public I putExtra(String name, char value) {
56+
intent.putExtra(name, value);
57+
return (I) this;
58+
}
59+
60+
public I putExtra(String name, short value) {
61+
intent.putExtra(name, value);
62+
return (I) this;
63+
}
64+
65+
public I putExtra(String name, int value) {
66+
intent.putExtra(name, value);
67+
return (I) this;
68+
}
69+
70+
public I putExtra(String name, long value) {
71+
intent.putExtra(name, value);
72+
return (I) this;
73+
}
74+
75+
public I putExtra(String name, float value) {
76+
intent.putExtra(name, value);
77+
return (I) this;
78+
}
79+
80+
public I putExtra(String name, double value) {
81+
intent.putExtra(name, value);
82+
return (I) this;
83+
}
84+
85+
public I putExtra(String name, String value) {
86+
intent.putExtra(name, value);
87+
return (I) this;
88+
}
89+
90+
public I putExtra(String name, CharSequence value) {
91+
intent.putExtra(name, value);
92+
return (I) this;
93+
}
94+
95+
public I putExtra(String name, Parcelable value) {
96+
intent.putExtra(name, value);
97+
return (I) this;
98+
}
99+
100+
public I putExtra(String name, Parcelable[] value) {
101+
intent.putExtra(name, value);
102+
return (I) this;
103+
}
104+
105+
public I putParcelableArrayListExtra(String name, ArrayList<? extends Parcelable> value) {
106+
intent.putParcelableArrayListExtra(name, value);
107+
return (I) this;
108+
}
109+
110+
public I putIntegerArrayListExtra(String name, ArrayList<Integer> value) {
111+
intent.putIntegerArrayListExtra(name, value);
112+
return (I) this;
113+
}
114+
115+
public I putStringArrayListExtra(String name, ArrayList<String> value) {
116+
intent.putStringArrayListExtra(name, value);
117+
return (I) this;
118+
}
119+
120+
public I putExtra(String name, Serializable value) {
121+
intent.putExtra(name, value);
122+
return (I) this;
123+
}
124+
125+
public I putExtra(String name, boolean[] value) {
126+
intent.putExtra(name, value);
127+
return (I) this;
128+
}
129+
130+
public I putExtra(String name, byte[] value) {
131+
intent.putExtra(name, value);
132+
return (I) this;
133+
}
134+
135+
public I putExtra(String name, short[] value) {
136+
intent.putExtra(name, value);
137+
return (I) this;
138+
}
139+
140+
public I putExtra(String name, char[] value) {
141+
intent.putExtra(name, value);
142+
return (I) this;
143+
}
144+
145+
public I putExtra(String name, int[] value) {
146+
intent.putExtra(name, value);
147+
return (I) this;
148+
}
149+
150+
public I putExtra(String name, long[] value) {
151+
intent.putExtra(name, value);
152+
return (I) this;
153+
}
154+
155+
public I putExtra(String name, float[] value) {
156+
intent.putExtra(name, value);
157+
return (I) this;
158+
}
159+
160+
public I putExtra(String name, double[] value) {
161+
intent.putExtra(name, value);
162+
return (I) this;
163+
}
164+
165+
public I putExtra(String name, String[] value) {
166+
intent.putExtra(name, value);
167+
return (I) this;
168+
}
169+
170+
public I putExtra(String name, Bundle value) {
171+
intent.putExtra(name, value);
172+
return (I) this;
173+
}
174+
175+
public I putExtras(Intent src) {
176+
intent.putExtras(src);
177+
return (I) this;
178+
}
179+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.androidannotations.api.builder;
2+
3+
import android.content.ComponentName;
4+
import android.content.Context;
5+
6+
public class ServiceIntentBuilder<I extends ServiceIntentBuilder<I>> extends IntentBuilder<I> {
7+
8+
public ServiceIntentBuilder(Context context, Class<?> clazz) {
9+
super(context, clazz);
10+
}
11+
12+
public ComponentName start() {
13+
return context.startService(intent);
14+
}
15+
16+
public boolean stop() {
17+
return context.stopService(intent);
18+
}
19+
}

‎AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/helper/ActivityIntentBuilder.java‎

Lines changed: 86 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,65 +15,110 @@
1515
*/
1616
package org.androidannotations.helper;
1717

18-
import static com.sun.codemodel.JMod.PUBLIC;
19-
18+
import com.sun.codemodel.*;
2019
import org.androidannotations.holder.HasIntentBuilder;
2120

22-
import com.sun.codemodel.JBlock;
23-
import com.sun.codemodel.JClass;
24-
import com.sun.codemodel.JClassAlreadyExistsException;
25-
import com.sun.codemodel.JConditional;
26-
import com.sun.codemodel.JExpr;
27-
import com.sun.codemodel.JMethod;
28-
import com.sun.codemodel.JVar;
21+
import static com.sun.codemodel.JExpr._new;
22+
import static com.sun.codemodel.JExpr._super;
23+
import static com.sun.codemodel.JMod.PRIVATE;
24+
import static com.sun.codemodel.JMod.PUBLIC;
25+
import static com.sun.codemodel.JMod.STATIC;
2926

3027
public class ActivityIntentBuilder extends IntentBuilder {
3128

29+
private static final int MIN_SDK_WITH_FRAGMENT_SUPPORT = 11;
30+
31+
private JFieldVar fragmentField;
32+
private JFieldVar fragmentSupportField;
33+
3234
public ActivityIntentBuilder(HasIntentBuilder holder, AndroidManifest androidManifest) {
3335
super(holder, androidManifest);
3436
}
3537

3638
@Override
3739
public void build() throws JClassAlreadyExistsException {
3840
super.build();
39-
createStart();
40-
createStartForResult();
41+
createAdditionalConstructor(); // See issue #541
42+
createAdditionalIntentMethods();
43+
overrideStartForResultMethod();
44+
}
45+
46+
private void createAdditionalIntentMethods() {
47+
if (hasFragmentInClasspath()) {
48+
// intent() with android.app.Fragment param
49+
JMethod method = holder.getGeneratedClass().method(STATIC | PUBLIC, holder.getIntentBuilderClass(), "intent");
50+
JVar fragmentParam = method.param(holder.classes().FRAGMENT, "fragment");
51+
method.body()._return(_new(holder.getIntentBuilderClass()).arg(fragmentParam));
52+
}
53+
if (hasFragmentSupportInClasspath()) {
54+
// intent() with android.support.v4.app.Fragment param
55+
JMethod method = holder.getGeneratedClass().method(STATIC | PUBLIC, holder.getIntentBuilderClass(), "intent");
56+
JVar fragmentParam = method.param(holder.classes().SUPPORT_V4_FRAGMENT, "supportFragment");
57+
method.body()._return(_new(holder.getIntentBuilderClass()).arg(fragmentParam));
58+
}
59+
}
60+
61+
@Override
62+
protected JClass getSuperClass() {
63+
JClass superClass = holder.refClass(org.androidannotations.api.builder.ActivityIntentBuilder.class);
64+
return superClass.narrow(builderClass);
4165
}
4266

43-
private void createStart() {
44-
JMethod method = holder.getIntentBuilderClass().method(PUBLIC, holder.codeModel().VOID, "start");
45-
method.body().invoke(contextField, "startActivity").arg(holder.getIntentField());
67+
private void createAdditionalConstructor() {
68+
if (hasFragmentInClasspath()) {
69+
fragmentField = addFragmentConstructor(holder.classes().FRAGMENT, "fragment_");
70+
}
71+
if (hasFragmentSupportInClasspath()) {
72+
fragmentSupportField = addFragmentConstructor(holder.classes().SUPPORT_V4_FRAGMENT, "fragmentSupport_");
73+
}
4674
}
4775

48-
private void createStartForResult() {
76+
private JFieldVar addFragmentConstructor(JClass fragmentClass, String fieldName) {
77+
JFieldVar fragmentField = holder.getIntentBuilderClass().field(PRIVATE, fragmentClass, fieldName);
78+
JExpression generatedClass = holder.getGeneratedClass().dotclass();
79+
80+
JMethod constructor = holder.getIntentBuilderClass().constructor(JMod.PUBLIC);
81+
JVar constructorFragmentParam = constructor.param(fragmentClass, "fragment");
82+
JBlock constructorBody = constructor.body();
83+
constructorBody.invoke("super").arg(constructorFragmentParam.invoke("getActivity")).arg(generatedClass);
84+
constructorBody.assign(fragmentField, constructorFragmentParam);
85+
86+
return fragmentField;
87+
}
88+
89+
private void overrideStartForResultMethod() {
90+
if (fragmentSupportField == null && fragmentField == null) {
91+
return;
92+
}
4993
JMethod method = holder.getIntentBuilderClass().method(PUBLIC, holder.codeModel().VOID, "startForResult");
94+
method.annotate(Override.class);
5095
JVar requestCode = method.param(holder.codeModel().INT, "requestCode");
51-
5296
JBlock body = method.body();
53-
JClass activityClass = holder.classes().ACTIVITY;
54-
JConditional condition = null;
55-
if (fragmentSupportField != null) {
56-
condition = body._if(fragmentSupportField.ne(JExpr._null()));
57-
condition._then() //
58-
.invoke(fragmentSupportField, "startActivityForResult").arg(holder.getIntentField()).arg(requestCode);
59-
}
60-
if (fragmentField != null) {
61-
if (condition == null) {
62-
condition = body._if(fragmentField.ne(JExpr._null()));
63-
} else {
64-
condition = condition._elseif(fragmentField.ne(JExpr._null()));
65-
}
66-
condition._then() //
67-
.invoke(fragmentField, "startActivityForResult").arg(holder.getIntentField()).arg(requestCode);
68-
}
69-
if (condition == null) {
70-
condition = body._if(contextField._instanceof(activityClass));
71-
} else {
72-
condition = condition._elseif(contextField._instanceof(activityClass));
73-
}
74-
condition._then() //
75-
.invoke(JExpr.cast(activityClass, contextField), "startActivityForResult").arg(holder.getIntentField()).arg(requestCode);
76-
condition._else() //
77-
.invoke(contextField, "startActivity").arg(holder.getIntentField());
97+
98+
JConditional condition = null;
99+
if (fragmentSupportField != null) {
100+
condition = body._if(fragmentSupportField.ne(JExpr._null()));
101+
condition._then() //
102+
.invoke(fragmentSupportField, "startActivityForResult").arg(holder.getIntentField()).arg(requestCode);
103+
}
104+
if (fragmentField != null) {
105+
if (condition == null) {
106+
condition = body._if(fragmentField.ne(JExpr._null()));
107+
} else {
108+
condition = condition._elseif(fragmentField.ne(JExpr._null()));
109+
}
110+
condition._then() //
111+
.invoke(fragmentField, "startActivityForResult").arg(holder.getIntentField()).arg(requestCode);
112+
}
113+
condition._else().invoke(_super(), "startForResult").arg(requestCode);
114+
}
115+
116+
protected boolean hasFragmentInClasspath() {
117+
boolean fragmentExistsInSdk = androidManifest.getMinSdkVersion() >= MIN_SDK_WITH_FRAGMENT_SUPPORT;
118+
return fragmentExistsInSdk && elementUtils.getTypeElement(CanonicalNameConstants.FRAGMENT) != null;
119+
}
120+
121+
protected boolean hasFragmentSupportInClasspath() {
122+
return elementUtils.getTypeElement(CanonicalNameConstants.SUPPORT_V4_FRAGMENT) != null;
78123
}
79124
}

0 commit comments

Comments
 (0)