-
Notifications
You must be signed in to change notification settings - Fork 2.3k
@SerialBackground : serial execution in background #309
Description
The @Background is nice for executing methods in a background thread. It uses a cached thread pool for this purpose.
If you call the same method multiple times in a raw, they are executed in parallel, and you have no guarantee on the execution order. For this kind of purpose, we need a way to execute tasks in background serially.
One way to fix this for now is to call com.googlecode.androidannotations.api.BackgroundExecutor.setExecutor(Executor) and set an executor with only one thread, but this means all background operations in the app will execute on this very same thread, which isn't good.
Another solution would be to create a new @SerialBackground or an annotation parameter to the @Background annotation to use a serial behavior.
The implementation should use a HandlerThread and a dedicated Handler.
Of course, we need a way to identify methods that will execute in the same HandlerThread.
We have different solutions here :
- Use one handler thread for each class instance. This is the most simple solution, but the less flexible. This would allow creation a "Store" class and ensure that all background calls on the instance of the class are executed serially
- Identify the targeted handler by a String name and store a static cache of "name" =>
Handler. This would mean the Threads are not going to be GCed. A usage example :
@EBean
public class MyClass {
@Background(serial="MyThreadName")
public void doStuffAsync() {
}
@Background(serial="MyThreadName")
public void doStuffAsync2() {
}
}The main component would look like this :
public class SerialBackgroundExecutor {
private static Map<String, Handler> handlersByName = new HashMap<String, Handler>();
public static synchronized void execute(String name, Runnable runnable) {
Handler handler = handlersByName.get(name);
if (handler == null) {
HandlerThread thread = new HandlerThread(name);
thread.start();
handler = new Handler(thread.getLooper());
handlersByName.put(name, handler);
}
handler.post(runnable);
}
}Feedback / input is quite welcome !