执行中的异步任务和队列OR延迟

时间:2015-10-04 20:57:53

标签: android android-asynctask queue

情景:

用户有一个项目列表,让我们说10个项目。每个项目都有一个Operation按钮,它调用AsyncTask进行Web调用。进行调用时,该项在执行任务期间显示微调器

问题:

有些用户滥用此功能,并快速按下更多操作按钮,一个接一个地快速拨号,过于频繁地执行网络通话。所以我希望能够以某种方式,一个接一个地执行每个AsyncTasks,执行之间延迟2秒。如果可能的话,我不想从AsyncTask切换到其他东西。所以基本上如果按下3个操作按钮,执行应该是:

- >操作1 - > 2秒延迟 - >操作2 - > 2秒延迟 - >操作3 - > ....

在Android中执行此操作的最佳方式是什么?

LE

我刚刚意识到了一些事情,为了执行我的任务,我运行了以下代码:

myTask = new MyTask();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
   myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
   myTask.execute();
}

嗯,我现在已经使用这段代码了很多时间,因为我知道在没有使用Executor的情况下,任务不再并行执行。所以似乎只做一个简单的myTask.execute()并添加一个Thread.sleep()使我的AsyncTasks一个接一个地按预期执行。

3 个答案:

答案 0 :(得分:1)

您需要维护需要执行的操作列表。 点击按钮添加列表中的任务,调用检查任务列表的方法,如果没有其他任务正在运行,则执行该方法。

onPostExecute方法中的

调用相同的方法来检查是否还有其他需要执行的任务/操作..

它可能不是您需要的完整代码......但可能会给您一些想法..

public class TestActivity extends AppCompatActivity {

    private static boolean isTaskRunning =false;
    static ArrayList<CustomTask> customTaskList = new ArrayList();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
    }

    public void onBtnClick(View view)
    {
        // create custom task with required values and actions 
        CustomTask customTask = new CustomTask();
        customTaskList.add(customTask);         

        checkAndExecuteTask();
    }


    private static void checkAndExecuteTask()
    {
        //checks if there is any task in the list and is there any other         running task
        if(customTaskList.size()>0 && !isTaskRunning) {
            new MyAsync(customTaskList.get(0)).execute();
        }
    }

    static class MyAsync extends AsyncTask<Void,Void,Void>
    {
        CustomTask currentCustomTask;

        public MyAsync(CustomTask customTask)
        {
            currentCustomTask = customTask;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            isTaskRunning= true;
        }

        @Override
        protected Void doInBackground(Void... voids) {

            // do your stuff
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            customTaskList.remove(currentCustomTask);
            isTaskRunning =false;
            checkAndExecuteTask(); // task is completed so check for another     task and execute (if any).
        }
    }

    class CustomTask
    {
        // create class with required fields and method
    }
}

答案 1 :(得分:1)

在android中有很多方法可以做到这一点。 一种方法是使用handler

你需要做的是,创建一个单独的线程并在其中运行handler.postDelayed。

private void startWebCall() {

    Thread thread = new Thread() {
        public void run() {
            Looper.prepare();

            final Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                   // Do your web calls here
                    handler.removeCallbacks(this);
                    Looper.myLooper().quit();
               }
            }, 2000);

            Looper.loop();
        }
    };
    thread.start();
} 

每当用户点击某个项目时,您都应该调用上述方法。

我能想到的另一种方法是使用IntentService

IntentService是一种用于在后台执行异步任务的服务。它维护着需要执行的任务的队列。它与上述方法的不同之处在于它按顺序执行这些任务。因此,当您向它发出请求进行网络呼叫时,它会将它们排队,进行第一次呼叫,然后在完成后进行第二次呼叫。因此,不同的Web调用不会并行执行。它们将按顺序执行,但在不同的线程中执行。它也是一种服务,因此它甚至可以在后台运行,即如果用户关闭应用程序。

This是一个很好的教程,可以开始使用IntentService。

除非工作人员需要做的工作非常简单,否则通常应避免使用AsyncTaks。 This博客解释了它的缺陷。

答案 2 :(得分:0)

此算法将根据您的要求执行:

ButtonA.onclick() {
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override public void run() {
            MytaskA.execute();
        }
    }, 2000);
}

ButtonB.onclick() {
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override public void run() {
            MytaskB.execute();
        }
    }, 2000);

}
ButtonC.onclick() {
    final Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override public void run() {
            MytaskC.execute();
        }
    }, 2000);

}