From 30c28d2d9fbc5cb178777a23f02c871e45651ff2 Mon Sep 17 00:00:00 2001 From: Thomas Bruyelle Date: Sun, 11 Aug 2013 14:40:32 +0200 Subject: [PATCH] Associate the handler to the main thread Previous implementation associate the handler to the current thread, which can not be the main thread. --- .../processing/UiThreadProcessor.java | 5 ++- .../test15/ThreadActivityTest.java | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/UiThreadProcessor.java b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/UiThreadProcessor.java index 685b514a7f..ebf1564a90 100644 --- a/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/UiThreadProcessor.java +++ b/AndroidAnnotations/androidannotations/src/main/java/org/androidannotations/processing/UiThreadProcessor.java @@ -33,6 +33,7 @@ import com.sun.codemodel.JDefinedClass; import com.sun.codemodel.JExpr; import com.sun.codemodel.JExpression; +import com.sun.codemodel.JInvocation; import com.sun.codemodel.JMethod; import com.sun.codemodel.JMod; import com.sun.codemodel.JOp; @@ -67,7 +68,9 @@ public void process(Element element, JCodeModel codeModel, EBeanHolder holder) t if (holder.handler == null) { JClass handlerClass = holder.classes().HANDLER; - holder.handler = holder.generatedClass.field(JMod.PRIVATE, handlerClass, "handler_", JExpr._new(handlerClass)); + JClass lClass = holder.classes().LOOPER; + JInvocation arg = JExpr._new(handlerClass).arg(lClass.staticInvoke(METHOD_MAIN_LOOPER)); + holder.handler = holder.generatedClass.field(JMod.PRIVATE, handlerClass, "handler_", arg); } if (delay == 0) { diff --git a/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/ThreadActivityTest.java b/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/ThreadActivityTest.java index 8ae00b7729..89e41f8f3b 100644 --- a/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/ThreadActivityTest.java +++ b/AndroidAnnotations/functional-test-1-5-tests/src/test/java/org/androidannotations/test15/ThreadActivityTest.java @@ -19,6 +19,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -35,6 +36,9 @@ import org.junit.runner.RunWith; import org.mockito.Mockito; +import android.os.Handler; +import android.os.Looper; + @RunWith(AndroidAnnotationsTestRunner.class) public class ThreadActivityTest { @@ -285,4 +289,35 @@ public void execute(Runnable command) { } } + @Test + public void assertHandlerWithMainThread() throws NoSuchFieldException, IllegalAccessException, InterruptedException { + /* + * For this test we need to recreate the activity in a separate thread, + * in order to check the handler is well associated to the main thread. + */ + final ThreadActivity_[] threadActivityHolder = new ThreadActivity_[1]; + + new Thread(new Runnable() { + @Override + public void run() { + synchronized (threadActivityHolder) { + threadActivityHolder[0] = new ThreadActivity_(); + threadActivityHolder[0].onCreate(null); + threadActivityHolder.notify(); + } + } + }).start(); + synchronized (threadActivityHolder) { + do { + threadActivityHolder.wait(); + } while(threadActivityHolder[0] == null); + } + + Field handlerField = ThreadActivity_.class.getDeclaredField("handler_"); + handlerField.setAccessible(true); + + Handler handler = (Handler) handlerField.get(threadActivityHolder[0]); + Assert.assertTrue("Handler field not associated to the main thread", handler.getLooper() == Looper.getMainLooper()); + } + }