Skip to content

Commit 3f3ea4f

Browse files
committed
Merge pull request androidannotations#1121 from Artyomcool/execution-thread-control-javadocs
add: JavaDocs for SupposeThread-feature
2 parents d962b9c + 6d67509 commit 3f3ea4f

File tree

3 files changed

+201
-93
lines changed

3 files changed

+201
-93
lines changed
Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,52 @@
11
package org.androidannotations.annotations;
22

3+
import org.androidannotations.api.BackgroundExecutor;
4+
35
import java.lang.annotation.ElementType;
46
import java.lang.annotation.Retention;
57
import java.lang.annotation.RetentionPolicy;
68
import java.lang.annotation.Target;
79

10+
/**
11+
* Ensures that the method is called from the background thread with (optionally) restrictions by allowed serials.
12+
* If it is not called from a supposed background thread, then {@link IllegalStateException}
13+
* will be thrown (by default).
14+
* <p/>
15+
* <blockquote> <b>Example</b> :
16+
* <p/>
17+
* <pre>
18+
* &#064;EBean
19+
* public class MyBean {
20+
*
21+
* &#064;SupposeBackground
22+
* boolean someMethodThatShouldNotBeCalledFromUiThread() {
23+
* //if this method will be called from the UI-thread an exception will be thrown
24+
* }
25+
*
26+
* &#064;SupposeBackground(serial = {"serial1", "serial2"})
27+
* boolean someMethodThatShouldBeCalledFromSerial1OrSerial2() {
28+
* //if this method will be called from another thread then a background thread with a
29+
* //serial "serial1" or "serial2", an exception will be thrown
30+
* }
31+
*
32+
* }
33+
* </pre>
34+
* <p/>
35+
* </blockquote>
36+
*
37+
* @see BackgroundExecutor#setWrongThreadListener(BackgroundExecutor.WrongThreadListener)
38+
* @see BackgroundExecutor#DEFAULT_WRONG_THREAD_LISTENER
39+
* @see BackgroundExecutor#checkBgThread(String...)
40+
*/
841
@Retention(RetentionPolicy.CLASS)
942
@Target(ElementType.METHOD)
1043
public @interface SupposeBackground {
1144

12-
String[] serial() default {};
45+
/**
46+
* Allowed serials to restrict a calling thread. If it is an empty list, then any background thread is allowed.
47+
*
48+
* @see BackgroundExecutor#checkBgThread(String...)
49+
*/
50+
String[] serial() default {};
1351

1452
}

AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/annotations/SupposeUiThread.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,35 @@
11
package org.androidannotations.annotations;
22

3+
import org.androidannotations.api.BackgroundExecutor;
4+
5+
import java.lang.IllegalStateException;
36
import java.lang.annotation.ElementType;
47
import java.lang.annotation.Retention;
58
import java.lang.annotation.RetentionPolicy;
69
import java.lang.annotation.Target;
710

811
/**
912
* Ensures that method is called from the UI thread. If it is not, then
10-
* {@link java.lang.IllegalStateException} will be thrown (by default).
11-
* //TODO how to change default
13+
* {@link IllegalStateException} will be thrown (by default).
14+
*
15+
* <blockquote> <b>Example</b> :
16+
*
17+
* <pre>
18+
* &#064;EBean
19+
* public class MyBean {
20+
*
21+
* &#064;SupposeUiThread
22+
* boolean someMethodThatShouldBeCalledOnlyFromUiThread() {
23+
* //if this method will be called from a background thread an exception will be thrown
24+
* }
25+
* }
26+
* </pre>
27+
*
28+
* </blockquote>
29+
*
30+
* @see BackgroundExecutor#setWrongThreadListener(BackgroundExecutor.WrongThreadListener)
31+
* @see BackgroundExecutor#DEFAULT_WRONG_THREAD_LISTENER
32+
* @see BackgroundExecutor#checkUiThread()
1233
*/
1334
@Retention(RetentionPolicy.CLASS)
1435
@Target(ElementType.METHOD)

AndroidAnnotations/androidannotations-api/src/main/java/org/androidannotations/api/BackgroundExecutor.java

Lines changed: 139 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -28,39 +28,51 @@
2828

2929
import android.os.Looper;
3030
import android.util.Log;
31+
import org.androidannotations.annotations.SupposeBackground;
32+
import org.androidannotations.annotations.SupposeUiThread;
3133

3234
public class BackgroundExecutor {
3335

3436
private static final String TAG = "BackgroundExecutor";
3537

3638
public static Executor DEFAULT_EXECUTOR = Executors.newScheduledThreadPool(2 * Runtime.getRuntime().availableProcessors());
3739
private static Executor executor = DEFAULT_EXECUTOR;
38-
public static final WrongThreadListener DEFAULT_WRONG_THREAD_LISTENER = new WrongThreadListener() {
39-
@Override
40-
public void onUiExpected() {
41-
throw new IllegalStateException("Method invocation is expected from the UI thread");
42-
}
43-
44-
@Override
45-
public void onBgExpected(String... expectedSerials) {
46-
if (expectedSerials.length == 0) {
47-
throw new IllegalStateException("Method invocation is expected from a background thread, but it was called from the UI thread");
48-
}
49-
throw new IllegalStateException("Method invocation is expected from one of serials " + Arrays.toString(expectedSerials) + ", but it was called from the UI thread");
50-
}
51-
52-
@Override
53-
public void onWrongBgSerial(String currentSerial, String... expectedSerials) {
54-
if (currentSerial == null) {
55-
currentSerial = "anonymous";
56-
}
57-
throw new IllegalStateException("Method invocation is expected from one of serials " + Arrays.toString(expectedSerials) + ", but it was called from " + currentSerial + " serial");
58-
}
59-
};
60-
private static WrongThreadListener wrongThreadListener = DEFAULT_WRONG_THREAD_LISTENER;
40+
41+
/**
42+
* The default invocation handler for wrong thread execution.
43+
* It just throws {@link IllegalStateException} with explanation what is going wrong.
44+
*
45+
* @see #setWrongThreadListener(BackgroundExecutor.WrongThreadListener)
46+
* @see SupposeBackground
47+
* @see SupposeUiThread
48+
*/
49+
public static final WrongThreadListener DEFAULT_WRONG_THREAD_LISTENER = new WrongThreadListener() {
50+
@Override
51+
public void onUiExpected() {
52+
throw new IllegalStateException("Method invocation is expected from the UI thread");
53+
}
54+
55+
@Override
56+
public void onBgExpected(String... expectedSerials) {
57+
if (expectedSerials.length == 0) {
58+
throw new IllegalStateException("Method invocation is expected from a background thread, but it was called from the UI thread");
59+
}
60+
throw new IllegalStateException("Method invocation is expected from one of serials " + Arrays.toString(expectedSerials) + ", but it was called from the UI thread");
61+
}
62+
63+
@Override
64+
public void onWrongBgSerial(String currentSerial, String... expectedSerials) {
65+
if (currentSerial == null) {
66+
currentSerial = "anonymous";
67+
}
68+
throw new IllegalStateException("Method invocation is expected from one of serials " + Arrays.toString(expectedSerials) + ", but it was called from " + currentSerial + " serial");
69+
}
70+
};
71+
72+
private static WrongThreadListener wrongThreadListener = DEFAULT_WRONG_THREAD_LISTENER;
6173

6274
private static final List<Task> tasks = new ArrayList<Task>();
63-
private static final ThreadLocal<String> currentSerial = new ThreadLocal<String>();
75+
private static final ThreadLocal<String> currentSerial = new ThreadLocal<String>();
6476

6577
/**
6678
* Execute a runnable after the given delay.
@@ -211,17 +223,19 @@ public static void setExecutor(Executor executor) {
211223
BackgroundExecutor.executor = executor;
212224
}
213225

214-
/**
215-
* Change the WrongThreadListener.
216-
* @param listener the new WrongThreadListener
217-
*/
218-
public static void setWrongThreadListener(WrongThreadListener listener) {
219-
BackgroundExecutor.wrongThreadListener = listener;
220-
}
226+
/**
227+
* Changes the default {@link WrongThreadListener}.
228+
* To restore the default one use {@link #DEFAULT_WRONG_THREAD_LISTENER}.
229+
*
230+
* @param listener the new {@link WrongThreadListener}
231+
*/
232+
public static void setWrongThreadListener(WrongThreadListener listener) {
233+
wrongThreadListener = listener;
234+
}
221235

222236
/**
223237
* Cancel all tasks having the specified <code>id</code>.
224-
*
238+
*
225239
* @param id
226240
* the cancellation identifier
227241
* @param mayInterruptIfRunning
@@ -253,57 +267,56 @@ public static synchronized void cancelAll(String id, boolean mayInterruptIfRunni
253267
}
254268
}
255269

256-
/**
257-
* Checks if current thread is UI and notifies
258-
* {@link BackgroundExecutor.WrongThreadListener#onUiExpected()} if it doesn't.
259-
*/
260-
public static void checkUiThread() {
261-
if (Looper.getMainLooper().getThread() != Thread.currentThread()) {
262-
wrongThreadListener.onUiExpected();
263-
}
264-
}
265-
266-
/**
267-
* Check if current thread is a background thread and, optionally, restrict it
268-
* with passed serials. If no serials passed and current thread is UI, then
269-
* {@link WrongThreadListener#onBgExpected(String...)} will be called.
270-
* If current thread is not UI and serials list is empty, then method just returns.
271-
* Otherwise, if method was called not during {@link Task} execution or the task has no
272-
* serial, then {@link WrongThreadListener#onWrongBgSerial(String, String...)} will be called
273-
* with null for the first parameter. If task has serial but passed serials don't contain that,
274-
* then {@link WrongThreadListener#onWrongBgSerial(String, String...)} will be called with
275-
* task's serial for the first parameter.
276-
*
277-
* @param serials (optional) list of allowed serials
278-
*/
279-
public static void checkBgThread(String... serials) {
280-
if (serials.length == 0) {
281-
if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
282-
wrongThreadListener.onBgExpected(serials);
283-
}
284-
return;
285-
}
286-
String current = currentSerial.get();
287-
if (current == null) {
288-
wrongThreadListener.onWrongBgSerial(null, serials);
289-
return;
290-
}
291-
for (String serial : serials) {
292-
if (serial.equals(current)) {
293-
return;
294-
}
295-
}
296-
wrongThreadListener.onWrongBgSerial(current, serials);
297-
}
270+
/**
271+
* Checks if the current thread is UI thread and notifies
272+
* {@link BackgroundExecutor.WrongThreadListener#onUiExpected()} if it doesn't.
273+
*/
274+
public static void checkUiThread() {
275+
if (Looper.getMainLooper().getThread() != Thread.currentThread()) {
276+
wrongThreadListener.onUiExpected();
277+
}
278+
}
279+
280+
/**
281+
* Checks if the current thread is a background thread and, optionally, restricts it
282+
* with passed serials. If no serials passed and current thread is the UI thread, then
283+
* {@link WrongThreadListener#onBgExpected(String...)} will be called.
284+
* If the current thread is not UI and serials list is empty, then this method just returns.
285+
* Otherwise, if the method was called not during {@link Task} execution or the task has no
286+
* serial, then the {@link WrongThreadListener#onWrongBgSerial(String, String...)} will be called
287+
* with null for the first parameter. If task has a serial but passed serials don't contain that,
288+
* then {@link WrongThreadListener#onWrongBgSerial(String, String...)} will be called with
289+
* the task's serial for the first parameter.
290+
*
291+
* @param serials (optional) list of allowed serials
292+
*/
293+
public static void checkBgThread(String... serials) {
294+
if (serials.length == 0) {
295+
if (Looper.getMainLooper().getThread() == Thread.currentThread()) {
296+
wrongThreadListener.onBgExpected(serials);
297+
}
298+
return;
299+
}
300+
String current = currentSerial.get();
301+
if (current == null) {
302+
wrongThreadListener.onWrongBgSerial(null, serials);
303+
return;
304+
}
305+
for (String serial : serials) {
306+
if (serial.equals(current)) {
307+
return;
308+
}
309+
}
310+
wrongThreadListener.onWrongBgSerial(current, serials);
311+
}
298312

299313
/**
300314
* Indicates whether a task with the specified <code>serial</code> has been
301315
* submitted to the executor.
302-
*
303-
* @param serial
304-
* the serial queue
316+
*
317+
* @param serial the serial queue
305318
* @return <code>true</code> if such a task has been submitted,
306-
* <code>false</code> otherwise
319+
* <code>false</code> otherwise
307320
*/
308321
private static boolean hasSerialRunning(String serial) {
309322
for (Task task : tasks) {
@@ -376,7 +389,7 @@ public void run() {
376389
}
377390

378391
try {
379-
currentSerial.set(serial);
392+
currentSerial.set(serial);
380393
execute();
381394
} finally {
382395
/* handle next tasks */
@@ -391,7 +404,7 @@ private void postExecute() {
391404
/* nothing to do */
392405
return;
393406
}
394-
currentSerial.set(null);
407+
currentSerial.set(null);
395408
synchronized (BackgroundExecutor.class) {
396409
/* execution complete */
397410
tasks.remove(this);
@@ -411,14 +424,50 @@ private void postExecute() {
411424
}
412425

413426
}
414-
/**
415-
* A callback interface to be notified when current thread, in which method has been invoked,
416-
* is wrong.
417-
* @see #setWrongThreadListener(WrongThreadListener)
418-
*/
419-
public static interface WrongThreadListener {
420-
void onUiExpected();
421-
void onBgExpected(String... expectedSerials);
422-
void onWrongBgSerial(String currentSerial, String... expectedSerials);
423-
}
427+
428+
/**
429+
* A callback interface to be notified when a method invocation is expected from another thread.
430+
*
431+
* @see #setWrongThreadListener(WrongThreadListener)
432+
* @see #checkUiThread()
433+
* @see #checkBgThread(String...)
434+
* @see SupposeUiThread
435+
* @see SupposeBackground
436+
*/
437+
public static interface WrongThreadListener {
438+
439+
/**
440+
* Will be called, if the method is supposed to be called from the UI-thread, but was called from a background
441+
* thread.
442+
*
443+
* @see SupposeUiThread
444+
* @see #setWrongThreadListener(WrongThreadListener)
445+
* @see #DEFAULT_WRONG_THREAD_LISTENER
446+
*/
447+
void onUiExpected();
448+
449+
/**
450+
* Will be called, if the method is supposed to be called from a background thread, but was called from the
451+
* UI-thread.
452+
*
453+
* @param expectedSerials a list of allowed serials. If any background thread is allowed the list will be empty.
454+
* @see SupposeBackground
455+
* @see #setWrongThreadListener(WrongThreadListener)
456+
* @see #DEFAULT_WRONG_THREAD_LISTENER
457+
*/
458+
void onBgExpected(String... expectedSerials);
459+
460+
/**
461+
* Will be called, if the method is supposed to be called from a background thread with one of
462+
* {@code expectedSerials}, but was called from a {@code currentSerial}. {@code currentSerial} will be null,
463+
* if it is called from a background thread without a serial.
464+
*
465+
* @param currentSerial the serial of caller thread or null if there is no serial
466+
* @param expectedSerials a list of allowed serials
467+
* @see SupposeBackground
468+
* @see #setWrongThreadListener(WrongThreadListener)
469+
* @see #DEFAULT_WRONG_THREAD_LISTENER
470+
*/
471+
void onWrongBgSerial(String currentSerial, String... expectedSerials);
472+
}
424473
}

0 commit comments

Comments
 (0)