Skip to content
This repository was archived by the owner on Feb 26, 2023. It is now read-only.
This repository was archived by the owner on Feb 26, 2023. It is now read-only.

@SerialBackground : serial execution in background #309

Closed

Description

@pyricau

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 !

Activity

  1. pyricau commented on Sep 1, 2012

    @pyricau
    ContributorAuthor

    Also notice the second solution doesn't allow a "one handler thread per instance" approach. I don't know whether this is good or bad :) .

  2. pyricau commented on Oct 25, 2012

    @pyricau
    ContributorAuthor

    This would mean the Threads are not going to be GCed

    We could use soft references for the handler cache to fix that.

  3. naixx commented on Nov 9, 2012

    @naixx
    Contributor

    What about Executors.newSingleThreadExecutor()?

  4. pyricau commented on Nov 10, 2012

    @pyricau
    ContributorAuthor

    You're right, it's probably even better then using Handlers.

    But still, we'd need to maintain a cache of string => single thread executor.

  5. calexo commented on Nov 11, 2012

    @calexo

    Really interested in that feature !!
    Just had the problem yesterday, and wondered how to solve it !

  6. naixx commented on Nov 11, 2012

    @naixx
    Contributor

    Hi @calexo!
    For now you can try the following code

    BackgroundExecutor.setExecutor(Executors.newSingleThreadExecutor())
    

    So, ALL your background tasks will be serial, thats can be a bit inconvenient.

  7. calexo commented on Nov 11, 2012

    @calexo

    In my case, serialising all my Background thread isn't a problem.
    So I tried BackgroundExecutor and it works !
    But still watching for an AA solution ;-)
    Thanks a lot !

  8. naixx commented on Nov 11, 2012

    @naixx
    Contributor

    @pyricau actually, Executors.newSingleThreadScheduledExecutor seems to be better solution. So that we can have delay and serial parameters. What do you think?

  9. yDelouis commented on Jun 19, 2013

    @yDelouis
    Contributor

    This should be documented in the wiki and closed.

  10. DayS commented on Jun 20, 2013

    @DayS
    Contributor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions