情景:
用户有一个项目列表,让我们说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一个接一个地按预期执行。
答案 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);
}