Lor*_*ori 8 android synchronization android-asynctask
是否可以进行AsyncTask.doInBackground同步 - 或以另一种方式实现相同的结果?
class SynchronizedTask extends AsyncTask {
@Override
protected synchronized Integer doInBackground(Object... params) {
// do something that needs to be completed
// before another doInBackground can be called
}
}
Run Code Online (Sandbox Code Playgroud)
在我的情况下,任何AsyncTask.execute()可以在前一个完成之前启动,但我只需要doInBackground在上一个任务完成后执行代码.
编辑:正确指出,同步仅适用于同一对象实例.遗憾的是,无法在同一对象实例上创建AsyncTask和调用execute()多次,如AsyncTask 文档的"线程规则"部分所述.
解决方案是使用自定义Executor来序列化任务,或者,如果您使用API 11或更高版本,AsyncTask.executeOnExecutor()则按照以下注释中的建议使用.
我发布了一个答案,显示了一个SerialExecutor可用于对将按顺序执行的任务进行排队的实现.
Lor*_*ori 16
理想情况下,我希望能够使用AsyncTask.executeOnExecutor()a SERIAL_EXECUTOR,但这仅适用于API级别11或更高级别:
new AsyncTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, params);
Run Code Online (Sandbox Code Playgroud)
为了定位11级以下的Android API,我最终实现了一个自定义类,它封装了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() {
}
}
}
Run Code Online (Sandbox Code Playgroud)
这可以扩展并用作以下的串行任务执行器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
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26082 次 |
| 最近记录: |