能在Android的AsyncTask doInBackground同步序列化执行任务? [英] Can an Android AsyncTask doInBackground be synchronized to serialize the task execution?

查看:150
本文介绍了能在Android的AsyncTask doInBackground同步序列化执行任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

时有可能使 AsyncTask.doInBackground 同步 - 或者达到相同的结果以另一种方式

Is it possible to make AsyncTask.doInBackground synchronized - or achieve the same result in another way?

class SynchronizedTask extends AsyncTask {

    @Override
    protected synchronized Integer doInBackground(Object... params) {
        // do something that needs to be completed 
        // before another doInBackground can be called
    }
}

在我的情况下,任何 AsyncTask.execute() A previous一个人完成,然后才能开始,但我需要执行code在 doInBackground 后,才previous的任务已经完成了。

In my case, any AsyncTask.execute() can be started before a previous one has completed, but I need to execute the code in doInBackground only after the previous task has finished.

修改:由于正确地指出,只有同步工作的同一个对象实例上。 不幸的是,它是不可能创建一个的AsyncTask 和呼叫执行()不止一次同一个对象实例,作为的AsyncTask 文档

EDIT: As correctly pointed out, the synchronization works only on the same object instance. Unfortunately, it is not possible to create an AsyncTask and call execute() more than once on the same object instance, as specified in the "Threading rules" section of the AsyncTask documentation.

解决方案是使用自定义执行人连载的任务,或者,如果你使用的API 11或以上,<一个href="http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor%28java.util.concurrent.Executor,%20Params...%29"相对=nofollow> AsyncTask.executeOnExecutor() ,如在下面的意见建议。

The solution is to use a custom Executor to serialize the tasks, or, if you use API 11 or above, AsyncTask.executeOnExecutor(), as suggested in the comments below.

我发布<一个href="http://stackoverflow.com/questions/9893813/can-an-android-asynctask-doinbackground-be-synchronized-to-serialize-the-task-ex#9906890">an回答的示出的实施方案一 SerialExecutor 可用于排队将要顺序执行的任务。

I posted an answer showing an implementation of a SerialExecutor that can be used to queue tasks that will be executed sequentially.

推荐答案

在理想情况下,我想能够使用<一个href="http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor%28java.util.concurrent.Executor,%20Params...%29"相对=nofollow> AsyncTask.executeOnExecutor() SERIAL_EXECUTOR ,但这只是用对于API级别11或以上:

Ideally, I'd like to be able to use AsyncTask.executeOnExecutor() with a SERIAL_EXECUTOR, but this is only available for API level 11 or above:

new AsyncTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, params);

要针对低于11级了Android的API,我最终实现它封装了的的ExecutorService =nofollow的> <$ C $为1。线程池大小的全code是开放源代码的这里

To target the Android APIs below level 11, I ended up implementing a custom class which encapsulates an ExecutorService with a thread pool size of 1. The full code is open-sourced here.

Executors.newFixedThreadPool(INT来确定nthreads)创建一个可重用操作关闭共享的无界队列的线程固定数量的线程池。在任何时候,至多确定nthreads 主题将是积极的处理任务。就我而言,确定nthreads 1,这意味着任务可以排队,但只有一个任务,在任何给定的时间执行。

Executors.newFixedThreadPool(int nThreads) creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue. At any point, at most nThreads threads will be active processing tasks. In my case, nThreads is 1, which means tasks can be queued, but only one task will be executed at any given time.

下面是code:

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() {

        }
    }
}

这可以扩展并用作串行任务执行中的活动

This can be extended and used as a serial task executor in an 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
            }
        }
    }
}

这篇关于能在Android的AsyncTask doInBackground同步序列化执行任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆