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

WorkingWithThreads

Csaba Kozák edited this page Mar 16, 2016 · 20 revisions

Since AndroidAnnotations 1.0

Get rid of AsyncTasks!

@Background

The @Background annotation indicates that a method will run in a thread other than the ui thread.

Usage example:

void myMethod() {
    someBackgroundWork("hello", 42);
}

@Background
void someBackgroundWork(String aParam, long anotherParam) {
    [...]
}

The method is executed on a separate thread, but this doesn't necessarily mean that a new thread will be started, because we use a shared cached thread pool executor (which can be replaced) to prevent creating too much threads.

This also means that two @Background methods may run in parallel

Id

Since AndroidAnnotations 3.0

If you want to cancel a background task, you can use the id field. Every task could then be cancelled by BackgroundExecutor.cancelAll("id");:

void myMethod() {
    someCancellableBackground("hello", 42);
    [...]
    boolean mayInterruptIfRunning = true;
    BackgroundExecutor.cancelAll("cancellable_task", mayInterruptIfRunning);
}

@Background(id="cancellable_task")
void someCancellableBackground(String aParam, long anotherParam) {
    [...]
}

Serial

Since AndroidAnnotations 3.0

By default, @Background method are processed in parallel. If you want them to be executed sequentially, you can use the serial field. All background tasks with the same serial will be executed sequentially:

void myMethod() {
    for (int i = 0; i < 10; i++)
        someSequentialBackgroundMethod(i);
}

@Background(serial = "test")
void someSequentialBackgroundMethod(int i) {
    SystemClock.sleep(new Random().nextInt(2000)+1000);
    Log.d("AA", "value : " + i);
}

Delay

Since AndroidAnnotations 3.0

If you need to add a delay before a background method is run, you can use the delay parameter:

@Background(delay=2000)
void doInBackgroundAfterTwoSeconds() {
}

@UiThread

The @UiThread annotation indicates that a method will run in the ui thread.

Usage example:

void myMethod() {
    doInUiThread("hello", 42);
}

@UiThread
void doInUiThread(String aParam, long anotherParam) {
    [...]
}

No more AsyncTask<Param, Progress, Result>!!

Delay

If you need to add a delay before a method is run on the UI Thread, you can use the delay parameter:

@UiThread(delay=2000)
void doInUiThreadAfterTwoSeconds() {
}

Propagation

Prior to 3.0, @Thread annotated method calls was always added in the handler execution queue to ensure that execution was done in Ui thread. Since 3.0, we kept the same behavior for compatibility purpose.

But, if you want to optimize UiThread calls, you may want to change propagation value to REUSE. In this configuration, the code will make a direct call to the method if current thread is already Ui thread. If not, we're falling back to handler call.

If you need to add a delay before a method is run on the UI Thread, you can use the delay parameter:

@UiThread(propagation = Propagation.REUSE)
void runInSameThreadIfOnUiThread() {
}

Note: If combined with delay, propagation will be ignored and the call will always be posted in handler execution queue.

Id

Since AndroidAnnotations 4.0.0

If you want to cancel a UI thread task, you can use the id field. Every task could then be cancelled by UiThreadExecutor.cancelAll("id");:

void myMethod() {
    someCancellableUiThreadMethod("hello", 42);
    [...]
    UiThreadExecutor.cancelAll("cancellable_task");
}

@UiThread(id="cancellable_task")
void someCancellableUiThreadMethod(String aParam, long anotherParam) {
    [...]
}

If the task is already started its execution, it will not be cancelled. Tasks with propagation REUSE cannot have an id, and cannot be cancelled.

@SupposeBackground

Since AndroidAnnotations 3.1

Annotate your methods to ensure they are called from a background thread with (optionally) restrictions by allowed serials. If it is not called from a supposed background thread, then IllegalStateException will be thrown (by default). The allowed IDs can be passed to the serial parameter, if nothing is passed, any ID is allowed.
If you want to override what happens when the method is not called on the supposed thread, pass an instance of BackgroundExecutor.WrongThreadListenerto BackgroundExecutor.setWrongThreadListener(). Its onBgExpected method will be invoked if the annotated method is called on the wrong thread, or its onWrongBgSerial will be invoked if the annotated method called on a background thread but with wrong IDs.

Usage example:

@EBean
public class MyBean {

  @SupposeBackground
  void someMethodThatShouldNotBeCalledFromUiThread() {
  //if this method will be called from the UI-thread an exception will be thrown
  }
  
  @SupposeBackground(serial = {"serial1", "serial2"})
  void someMethodThatShouldBeCalledFromSerial1OrSerial2() {
  //if this method will be called from another thread then a background thread with a
  //serial "serial1" or "serial2", an exception will be thrown
  }
}

@SupposeUiThread

Since AndroidAnnotations 3.1

Annotate your methods to ensure they are called from the UI thread. If they are not, then IllegalStateException will be thrown (by default).
If you want to override what happens when the method is not called on the UI thread, pass an instance of BackgroundExecutor.WrongThreadListenerto BackgroundExecutor.setWrongThreadListener(). Its onUiExpected method will be invoked if the annotated method is called on the wrong thread.

Usage example:

@EBean
public class MyBean {

  @SupposeUiThread
  void someMethodThatShouldBeCalledOnlyFromUiThread() {
  //if this method will be called from a background thread an exception will be thrown
  }

}

Using AndroidAnnotations

Questions?

Enjoying AndroidAnnotations

Improving AndroidAnnotations

Extending AndroidAnnotations

Clone this wiki locally