最近做个项目在做网络请求的时候很多时候会出现例如下面的情况:
点击按钮做网络请求,如果被快速点击,会发起很多次重复请求,如果加上activity来回跳转,可能导致奔溃。
这绝对不是好情况。如果设定一个全局变量来检测是否上一次工作已经完成,多线程+线程同步,是挺麻烦的。
下面的方式也是有一个成员变量,类型是异步任务:AsyncTask,当然可以不这么做,但是有些库不提供异步请求,所以建议这么做,也省去Handler的请求,但是缺点也明显,就是一个实例只能被execute一次,也就是说每次执行都要new一次,当然可以通过创建一个类来继承。
AsyncTask接口提供了四个方法:onPreExecute,onPostExecute,doInBackground,onProgressUpdate
除了doInBackground,其他方法都在Main线程里运行。
execute启动任务,cancel取消任务。execute后运行顺序就不用说了,从字眼上就看出来了。注意的是cancel取消并不会打断doInBackground的运行,当参数是true会打断doInBackground后回调postExecutede;如果为false则不会打断。
介绍完AsyncTask,开始上思路。
创建一个MyTask接口,用于定义在onPreExecute,onPostExecute,doInBackground调用每个实例实现的代码。
public interface MyTaskInterface {
void PreCall(Object...params);//在请求前作初始化,尤其是UI的更新
void Doing(Object...param);
void PostCall(Object...param);//在请求完成后做接下来的工作,尤其是UI更新
}
在定义一个继承了AsyncTask接口的类:
public class MyTask extends AsyncTask<Void,Void,Void>{
DBInterface myTaskInterface = null;
public MyTask(MyTaskInterface myTaskInterface)
{
this.myTaskInterface= myTaskInterface;
this.execute();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
dbInterface.PreCall();
}
@Override
protected Void doInBackground(Void... params) {
myTaskInterface .Doing();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
myTaskInterface.PostCall();
super.onPostExecute(aVoid);
}
}
把关的方法,可以防止多次new或者多次请求:
private MyTask task = null;
public void runAsyncTask(MyTaskInterface myTaskInterface)
{
if (task != null) {
switch (task.getStatus()) {
case RUNNING:
return;
case PENDING:
task.cancel(false);
break;
}
task = new MyTask(myTaskInterface);
}
调用该方法后会判断task的状态,是否为空,是否正在运行,还是已经运行完毕。
在重复多次运行该方法,也不会重复运行请求的代码。
End...