diff --git a/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/ReceiverAction.java b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/ReceiverAction.java index e4ab726644..ae24468967 100644 --- a/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/ReceiverAction.java +++ b/AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/ReceiverAction.java @@ -77,12 +77,12 @@ public @interface ReceiverAction { /** - * Define the action's name. If this field isn't set the annotated method - * name will be used. + * Define a set of actions this method should handle. If this field isn't + * set the annotated method name will be used. * - * @return the action's name + * @return the actions */ - String value() default ""; + String[] value() default {}; /** * Define a set of data schemes to filter the Intent. If this field isn't diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/ReceiverActionHandler.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/ReceiverActionHandler.java index 45ae9e3014..b94eabdf30 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/ReceiverActionHandler.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/handler/ReceiverActionHandler.java @@ -79,41 +79,40 @@ public void process(Element element, EReceiverHolder holder) throws Exception { ReceiverAction annotation = element.getAnnotation(ReceiverAction.class); String[] dataSchemes = annotation.dataSchemes(); - String extraKey = annotation.value(); - if (extraKey.isEmpty()) { - extraKey = methodName; + String[] actions = annotation.value(); + if (actions.length == 0) { + actions = new String[] { methodName }; } - JFieldVar actionKeyField = createStaticActionField(holder, extraKey, methodName); - JFieldVar dataSchemesField = createStaticDataSchemesField(holder, dataSchemes, methodName); + JFieldVar actionKeyField = createStaticField(holder, "actions", methodName, actions); + JFieldVar dataSchemesField = createStaticField(holder, "dataSchemes", methodName, dataSchemes); addActionInOnReceive(holder, executableElement, methodName, actionKeyField, dataSchemesField); } - private JFieldVar createStaticActionField(EReceiverHolder holder, String extraKey, String methodName) { - String staticFieldName = CaseHelper.camelCaseToUpperSnakeCase("action", methodName, null); - return holder.getGeneratedClass().field(PUBLIC | STATIC | FINAL, classes().STRING, staticFieldName, lit(extraKey)); - } + private JFieldVar createStaticField(EReceiverHolder holder, String prefix, String methodName, String[] values) { + String staticFieldName = CaseHelper.camelCaseToUpperSnakeCase(prefix, methodName, null); - private JFieldVar createStaticDataSchemesField(EReceiverHolder holder, String[] dataSchemes, String methodName) { - if (dataSchemes == null || dataSchemes.length == 0) { + if (values == null || values.length == 0) { return null; + } else if (values.length == 1) { + return holder.getGeneratedClass().field(PUBLIC | STATIC | FINAL, classes().STRING, staticFieldName, lit(values[0])); + } - JClass listOfStrings = classes().LIST.narrow(classes().STRING); - String staticFieldName = CaseHelper.camelCaseToUpperSnakeCase("dataSchemes", methodName, null); JInvocation asListInvoke = classes().ARRAYS.staticInvoke("asList"); - for (String scheme : dataSchemes) { + for (String scheme : values) { asListInvoke.arg(scheme); } - + JClass listOfStrings = classes().LIST.narrow(classes().STRING); return holder.getGeneratedClass().field(PUBLIC | STATIC | FINAL, listOfStrings, staticFieldName, asListInvoke); } - private void addActionInOnReceive(EReceiverHolder holder, ExecutableElement executableElement, String methodName, JFieldVar actionKeyField, JFieldVar dataSchemesField) { - // If action match, call the method - JExpression filterCondition = actionKeyField.invoke("equals").arg(holder.getOnReceiveIntentAction()); + private void addActionInOnReceive(EReceiverHolder holder, ExecutableElement executableElement, String methodName, JFieldVar actionsField, JFieldVar dataSchemesField) { + String actionsInvoke = getInvocationName(actionsField); + JExpression filterCondition = actionsField.invoke(actionsInvoke).arg(holder.getOnReceiveIntentAction()); if (dataSchemesField != null) { - filterCondition = filterCondition.cand(dataSchemesField.invoke("contains").arg(holder.getOnReceiveIntentDataScheme())); + String dataSchemesInvoke = getInvocationName(dataSchemesField); + filterCondition = filterCondition.cand(dataSchemesField.invoke(dataSchemesInvoke).arg(holder.getOnReceiveIntentDataScheme())); } JBlock callActionBlock = holder.getOnReceiveBody()._if(filterCondition)._then(); @@ -142,6 +141,14 @@ private void addActionInOnReceive(EReceiverHolder holder, ExecutableElement exec callActionBlock._return(); } + private String getInvocationName(JFieldVar field) { + JClass listOfStrings = classes().LIST.narrow(classes().STRING); + if (field.type().fullName().equals(listOfStrings.fullName())) { + return "contains"; + } + return "equals"; + } + private static class ExtraHandler extends ExtraParameterHandler { public ExtraHandler(ProcessingEnvironment processingEnvironment) { diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EReceiverHolder.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EReceiverHolder.java index c9255c0db2..848dfaea30 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EReceiverHolder.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/holder/EReceiverHolder.java @@ -24,14 +24,12 @@ import com.sun.codemodel.JBlock; import com.sun.codemodel.JExpr; -import com.sun.codemodel.JFieldVar; import com.sun.codemodel.JInvocation; import com.sun.codemodel.JMethod; import com.sun.codemodel.JVar; public class EReceiverHolder extends EComponentHolder { - private JFieldVar contextField; private JBlock onReceiveBody; private JVar onReceiveIntentAction; private JVar onReceiveIntentDataScheme; @@ -45,13 +43,15 @@ public EReceiverHolder(ProcessHolder processHolder, TypeElement annotatedElement @Override protected void setContextRef() { - contextField = generatedClass.field(PRIVATE, classes().CONTEXT, "context_"); - contextRef = contextField; + if (init == null) { + setInit(); + } } @Override protected void setInit() { init = generatedClass.method(PRIVATE, codeModel().VOID, "init_"); + contextRef = init.param(classes().CONTEXT, "context"); if (onReceiveMethod == null) { createOnReceive(); } @@ -63,14 +63,18 @@ private void createOnReceive() { onReceiveIntent = onReceiveMethod.param(classes().INTENT, "intent"); onReceiveMethod.annotate(Override.class); onReceiveBody = onReceiveMethod.body(); - onReceiveBody.assign(getContextField(), onReceiveContext); - onReceiveBody.invoke(getInit()); + onReceiveBody.invoke(getInit()).arg(onReceiveContext); onReceiveBody.invoke(JExpr._super(), onReceiveMethod).arg(onReceiveContext).arg(onReceiveIntent); + } - JInvocation getActionInvocation = JExpr.invoke(onReceiveIntent, "getAction"); - JInvocation getDataSchemeInvocation = JExpr.invoke(onReceiveIntent, "getScheme"); - onReceiveIntentAction = onReceiveBody.decl(classes().STRING, "action", getActionInvocation); - onReceiveIntentDataScheme = onReceiveBody.decl(classes().STRING, "dataScheme", getDataSchemeInvocation); + private void setOnReceiveIntentAction() { + JInvocation getActionInvocation = JExpr.invoke(getOnReceiveIntent(), "getAction"); + onReceiveIntentAction = getOnReceiveBody().decl(classes().STRING, "action", getActionInvocation); + } + + private void setOnReceiveIntentDataScheme() { + JInvocation getDataSchemeInvocation = JExpr.invoke(getOnReceiveIntent(), "getScheme"); + onReceiveIntentDataScheme = getOnReceiveBody().decl(classes().STRING, "dataScheme", getDataSchemeInvocation); } public JMethod getOnReceiveMethod() { @@ -103,22 +107,15 @@ public JVar getOnReceiveContext() { public JVar getOnReceiveIntentAction() { if (onReceiveIntentAction == null) { - createOnReceive(); + setOnReceiveIntentAction(); } return onReceiveIntentAction; } public JVar getOnReceiveIntentDataScheme() { if (onReceiveIntentDataScheme == null) { - createOnReceive(); + setOnReceiveIntentDataScheme(); } return onReceiveIntentDataScheme; } - - public JFieldVar getContextField() { - if (contextField == null) { - setContextRef(); - } - return contextField; - } } diff --git a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/ereceiver/ReceiverWithActions.java b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/ereceiver/ReceiverWithActions.java index c636bbe13e..4666bcc2bd 100644 --- a/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/ereceiver/ReceiverWithActions.java +++ b/AndroidAnnotations/functional-test-1-5/src/main/java/org/androidannotations/test15/ereceiver/ReceiverWithActions.java @@ -25,6 +25,16 @@ @EReceiver public class ReceiverWithActions extends BroadcastReceiver { + public static final String ACTION_SIMPLE_TEST = "ACTION_SIMPLE_TEST"; + public static final String ACTION_SCHEME_TEST = "ACTION_SCHEME_TEST"; + public static final String ACTION_PARAMETER_TEST = "ACTION_PARAMETER_TEST"; + public static final String ACTION_MULTIPLE_TEST_1 = "ACTION_MULTIPLE_TEST_1"; + public static final String ACTION_MULTIPLE_TEST_2 = "ACTION_MULTIPLE_TEST_2"; + public static final String ACTION_EXTRA_PARAMETER_TEST = "ACTION_EXTRA_PARAMETER_TEST"; + public static final String EXTRA_ARG_NAME1 = "thisExtraHasAnotherName"; + public static final String EXTRA_ARG_NAME2 = "thisIsMyParameter"; + public static final String DATA_SCHEME = "http"; + public boolean simpleActionReceived = false; public boolean actionWithSchemeReceived = false; @@ -34,29 +44,36 @@ public class ReceiverWithActions extends BroadcastReceiver { public boolean extraParameterActionReceived = false; public String extraParameterActionValue = null; + public int multipleActionCall = 0; + @Override public void onReceive(Context context, Intent intent) { } - @ReceiverAction("ACTION_SIMPLE_TEST") + @ReceiverAction(ACTION_SIMPLE_TEST) public void onSimpleAction() { simpleActionReceived = true; } - @ReceiverAction(value = "ACTION_SCHEME_TEST", dataSchemes = "http") + @ReceiverAction(value = ACTION_SCHEME_TEST, dataSchemes = DATA_SCHEME) public void onActionWithReceiver() { actionWithSchemeReceived = true; } - @ReceiverAction("ACTION_PARAMETER_TEST") + @ReceiverAction(ACTION_PARAMETER_TEST) public void onParameterAction(@ReceiverAction.Extra String thisIsMyParameter) { parameterActionReceived = true; parameterActionValue = thisIsMyParameter; } - @ReceiverAction("ACTION_EXTRA_PARAMETER_TEST") - public void onExtraParameterAction(@ReceiverAction.Extra("thisExtraHasAnotherName") String thisIsAParameter) { + @ReceiverAction(ACTION_EXTRA_PARAMETER_TEST) + public void onExtraParameterAction(@ReceiverAction.Extra(EXTRA_ARG_NAME1) String thisIsAParameter) { extraParameterActionReceived = true; extraParameterActionValue = thisIsAParameter; } + + @ReceiverAction({ ACTION_MULTIPLE_TEST_1, ACTION_MULTIPLE_TEST_2 }) + public void onMultipleActions() { + multipleActionCall++; + } } diff --git a/AndroidAnnotations/functional-test-1-5/src/test/java/org/androidannotations/test15/ereceiver/ReceiverWithActionsTest.java b/AndroidAnnotations/functional-test-1-5/src/test/java/org/androidannotations/test15/ereceiver/ReceiverWithActionsTest.java index 674e6f0652..7fa0064889 100644 --- a/AndroidAnnotations/functional-test-1-5/src/test/java/org/androidannotations/test15/ereceiver/ReceiverWithActionsTest.java +++ b/AndroidAnnotations/functional-test-1-5/src/test/java/org/androidannotations/test15/ereceiver/ReceiverWithActionsTest.java @@ -29,6 +29,8 @@ @RunWith(RobolectricTestRunner.class) public class ReceiverWithActionsTest { + private static final String EXTRA_PARAMETER_VALUE = "string value"; + private ReceiverWithActions receiver; @Before @@ -38,14 +40,14 @@ public void setup() { @Test public void onSimpleActionTest() { - receiver.onReceive(Robolectric.application, new Intent("ACTION_SIMPLE_TEST")); + receiver.onReceive(Robolectric.application, new Intent(ReceiverWithActions.ACTION_SIMPLE_TEST)); assertTrue(receiver.simpleActionReceived); } @Test public void onActionWithReceiverTest() { - Intent intent = new Intent("ACTION_SCHEME_TEST", Uri.parse("http://androidannotations.org")); + Intent intent = new Intent(ReceiverWithActions.ACTION_SCHEME_TEST, Uri.parse(ReceiverWithActions.DATA_SCHEME + "://androidannotations.org")); receiver.onReceive(Robolectric.application, intent); assertTrue(receiver.actionWithSchemeReceived); @@ -53,21 +55,34 @@ public void onActionWithReceiverTest() { @Test public void onParameterActionTest() { - Intent intent = new Intent("ACTION_PARAMETER_TEST"); - intent.putExtra("thisIsMyParameter", "string value"); + Intent intent = new Intent(ReceiverWithActions.ACTION_PARAMETER_TEST); + intent.putExtra(ReceiverWithActions.EXTRA_ARG_NAME2, EXTRA_PARAMETER_VALUE); receiver.onReceive(Robolectric.application, intent); assertTrue(receiver.parameterActionReceived); - assertEquals("string value", receiver.parameterActionValue); + assertEquals(EXTRA_PARAMETER_VALUE, receiver.parameterActionValue); } @Test public void onExtraParameterActionTest() { - Intent intent = new Intent("ACTION_EXTRA_PARAMETER_TEST"); - intent.putExtra("thisExtraHasAnotherName", "string value"); + Intent intent = new Intent(ReceiverWithActions.ACTION_EXTRA_PARAMETER_TEST); + intent.putExtra(ReceiverWithActions.EXTRA_ARG_NAME1, EXTRA_PARAMETER_VALUE); receiver.onReceive(Robolectric.application, intent); assertTrue(receiver.extraParameterActionReceived); - assertEquals("string value", receiver.extraParameterActionValue); + assertEquals(EXTRA_PARAMETER_VALUE, receiver.extraParameterActionValue); + } + + @Test + public void onMultipleActionsTest() { + assertEquals(0, receiver.multipleActionCall); + + Intent intent = new Intent(ReceiverWithActions.ACTION_MULTIPLE_TEST_1); + receiver.onReceive(Robolectric.application, intent); + assertEquals(1, receiver.multipleActionCall); + + intent = new Intent(ReceiverWithActions.ACTION_MULTIPLE_TEST_2); + receiver.onReceive(Robolectric.application, intent); + assertEquals(2, receiver.multipleActionCall); } }