Asynctask和队列OR延迟执行
用户有一个项目列表,比方说10个项目。每个项目都有一个操作按钮,它调用一个可以进行Web通话的AsyncTask。当调用时,该项目任务的执行过程中会显示一个微调
问题:
一些用户的滥用这一点,并快速按下多个操作按钮,quicklt此起彼伏,执行网络电话太频繁。所以我希望能够以某种方式,在执行之间延迟2秒执行每个AsyncTasks。如果可能的话,我不想从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按照预期一个接一个地执行。
您需要维护一个需要执行的操作列表。 单击按钮添加列表中的任务,调用一个方法,检查任务列表并执行它,如果没有其他任务正在运行..
在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
}
}
有许多的你可以在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是用于在后台执行异步任务的服务。它维护着它需要做的任务的队列。与上述方法不同的是,它按顺序执行这些任务。因此,当您向网络电话发出请求时,它会将它们排队,进行第一个呼叫,然后在完成后它将进行第二个呼叫。所以不同的网络电话将不会并行执行。它们将按顺序执行,但执行的是另一个线程。它也是一种服务,所以它可以在后台运行,即用户关闭应用程序。
This是一个很好的教程,以开始使用IntentService。
应该避免使用AsyncTaks,除非需要做的工作非常简单。 This博客解释了它的陷阱。
谢谢你的回答,它确实看起来像它做我需要的东西,但我想使用现有的AsyncTask实现。目前不需要IntentService,因为操作很简单,并且需要不断更新接口。 – Alin
该算法将做按您的要求:
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);
}
也许我失去了一些东西,但如果我按接连3个的操作按键之一,在过去2个项目将在几乎同时进行,因为有将是最后2个线程的睡眠时间为2秒,几毫秒让我按下按钮... – Alin
如何使用进度对话框?当任务正在运行时显示它..当进度对话框在屏幕上可见时..用户将无法触及其他操作按钮...当任务完成时..关闭onPostExecute方法中的对话..这样将只有一个任务将运行.. – Tarun
另一种选择是维护需要执行的操作的列表....在点击按钮上添加动作到列表..并调用一个方法来检查是否已经有一个正在运行的任务。它没有任何运行..它执行数组列表中的操作.....在后执行方法从数组列表中删除操作..并调用相同的方法来检查是否有任何其他操作需要被执行.... – Tarun