前言:
其实我不太敢写这篇文章,因为里面为了达成目的,用了一些不是很好的方法。
正文:
如果你正在用AsyncTask写一个下载东西的功能,那么也可能需要取消下载。知道AsyncTask的应该都知道其自带了onCancelled()方法,但是呢,onCncelled只能取消执行onPostExecute方法,而不能取消doInBackground。所以呢,为了达到目的,我得多作几步处理,中心思想如下。
首先,我们得声明一个标记callFinish来告诉线程,该结束doInBackground了。
其次,当事件触发取消的时候,将callFinish标记为true。
接着,调用cancel(true)方法,但不能取消doInbackground。
最后,再执行一边doInbackground,由于callFinish为true,所以可以直接进入onPostExecute。
当然了,为了避免onPostExecute中结果的混淆,我们可以设置另外一个bool标记,让用户区分哪一个结果值是正常的,哪一个是不正常的(正常?不正常?语言表述有问题,呵呵,意会就行!)。
好了,上代码。
(1)初始化:
boolean callFinish = false;
HelloWorld mHelloWorld = new HelloWorld();
(2)HelloWorld:
public class HelloWorld extends AsyncTask<Object, Object,Object> {
@Override
protected Boolean doInBackground(Object... params) {
boolean download = false;
do{
<处理数据>
download = true;
callFinish = true; //处理结束后赋值为true
}while(!callFinish);
returndownload;
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (result) {
Toast.makeText(mContext,
"下载成功",
Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(mContext,
"取消下载",
Toast.LENGTH_SHORT).show();
}
}
@Override
protected void onCancelled() {
super.onCancelled();
execFinish();
}
}
(3)下达取消指令:
public void cancelDownLoad() {
execFinish();
Toast.makeText(mContext, “停止下载”,
Toast.LENGTH_SHORT).show();
}
private void execFinish() {
callFinish = true;
mHelloWorld.cancel(true);
mHelloWorld.execute(-2);//不一定要写-2
}
以上便是不择手段地下达取消指令的中心思想。接下来要说的是处理超时的手段。很多情况下,数据请求有一个最大请求时间,因为进度条一直这么不断地转啊转啊也会让用户不爽。
设置数据请求的超时时间很简单,就是在执行的同时再起一个线程,当到达超时时间后,发现数据处理还是没有完成,那么就会进行其他操作,这里,姐的手段比较狠,超时了,姐就cancel掉它,当然也有人缓和一点,弄点别的啥,因项目情况而议吧。看代码就明了了。
@Override
protected void onPreExecute() {
super.onPreExecute();
if(alertDialog!= null && !alertDialog.isShowing()){
alertDialog.show();
}
m.start(); //另起的线程在这里!!!不一定要放这里哦,其他地方也行,只要能执行到。。
// 不想用m.start()也行,直接用
// mHandler.postDelayed(new Runnable() {
// @Override
// public void run() {
// }
// }, 18000);
//也可以,但我喜欢用前者,维护性和扩展性都好,唉。。。深受需求变更毒害的娃儿伤不起啊。
}
}
private Thread m = new Thread(new Runnable() {
@Override
public void run() {
try {
m.sleep(18000); //睡个18秒再执行。。。话说10秒就是姐等待的极限了。
mHandler.sendEmptyMessage(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
private Handler mHandler = new Handler(){
@Override
public void handleMessage(android.os.Message msg) {
if(alertDialog!=null&&alertDialog.isShowing()){
alertDialog.dismiss();
cancelDownLoad();
}
}
};
好了,讲完取消AsyncTask和超时处理,现在该讲讲一些注意事项了。其实也没啥太多注意事项,就两点。
1.不能在doInBackground中做任何UI方面的操作,什么setText啊,Toast啊,一律别用,要用就交给Handler。
2.AsyncTask会自动结束自己的线程,所以不要费心去关闭线程。其他类型的线程用完了可要关掉哦!
另外一种异步线程,将在下一篇中介绍。Looper+Thread!