В идеале я хотел бы иметь возможность использовать AsyncTask.executeOnExecutor()
с SERIAL_EXECUTOR
, но это доступно только для API уровня 11 или выше:
new AsyncTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, params);
Чтобы настроить API-интерфейсы Android ниже уровня 11, я реализовал собственный класс, который инкапсулирует ExecutorService
с размером пула потоков 1. Полный код здесь с открытым исходным кодом здесь .
Executors.newFixedThreadPool(int nThreads)
создает пул потоков, который повторно использует фиксированное количество потоков, работающих в общей неограниченной очереди. В любой момент не более nThreads
потоков будут активными задачами обработки. В моем случае nThreads
равно 1, что означает, что задачи могут быть поставлены в очередь, но в любой момент времени будет выполняться только одна задача.
Вот код:
public abstract class SerialExecutor {
private final ExecutorService mExecutorService;
public SerialExecutor() {
mExecutorService = Executors.newFixedThreadPool(1);
}
public void queue(Context context, TaskParams params) {
mExecutorService.submit(new SerialTask(context, params));
}
public void stop() {
mExecutorService.shutdown();
}
public abstract void execute(TaskParams params);
public static abstract class TaskParams { }
private class SerialTask implements Runnable {
private final Context mContext;
private final TaskParams mParams;
public SerialTask(Context context, TaskParams params) {
mContext = context;
mParams = params;
}
public void run() {
execute(mParams);
Activity a = (Activity) mContext;
a.runOnUiThread(new OnPostExecute());
}
}
/**
* Used to notify the UI thread
*/
private class OnPostExecute implements Runnable {
public void run() {
}
}
}
Это можно расширить и использовать в качестве исполнителя последовательных задач в Activity
:
public class MyActivity extends Activity {
private MySerialExecutor mSerialExecutor;
@Override
public void onCreate(Bundle savedInstanceState) {
// ...
mSerialExecutor = new MySerialExecutor();
}
@Override
protected void onDestroy() {
if (mSerialExecutor != null) {
mSerialExecutor.stop();
}
super.onDestroy();
}
public void onTrigger(int param) {
mSerialExecutor.queue(this, new MySerialExecutor.MyParams(param));
}
private static class MySerialExecutor extends SerialExecutor {
public MySerialExecutor() {
super();
}
@Override
public void execute(TaskParams params) {
MyParams myParams = (MyParams) params;
// do something...
}
public static class MyParams extends TaskParams {
// ... params definition
public MyParams(int param) {
// ... params init
}
}
}
}