您的位置:首页 > 移动开发 > Android开发

每周总结20130829——Android异步任务

2013-08-29 14:46 211 查看

Android异步任务——AsyncTask

Android开发中常常会犯的错误是:在其他线程中修改UI部分,于是程序直接出错终于,显示的错误是Only the original thread that created a view hierarchy can touch its views。这是由于Android系统的限制,其他线程没有资格对UI动刀子。为解决后台任务与UI交互的问题,我经常使用的方案是开辟一个线程处理后台任务,然后在这个线程中向UI线程的Handler发送消息,由Handler处理消息进而修改UI元素。这并不是一个在所有场合都适用的方案,首先Thread本身就是相对重量级的,用得不好容易出错;其次,有时候可能只有一个消息,为了处理这一个消息去使用Handler不太爽吧?AsyncTask正是为了在没有太复杂需求的场合中,轻松地与UI线程交互而存在。

AsyncTask与Thread有相似之处,都需要继承并实现一些方法才能使用。AsyncTask是一个泛型类,在继承时需要指定三个参数类型(形如这样的形式:AsyncTask<Params, Progress, Result>),这三个参数类型分别是三个方法的参数类型或返回值类型:

方法1:abstract Result doInBackground(Params... params)

方法2:void onProgressUpdate(Progress... values)

/**其实publishProgress方法也是这个类型的参数,不过这个方法不需要自己重写,在doInBackground中调用即可**/

方法3:void onPostExecute(Result result)

从声明可以看出,方法1是一个抽象方法,子类中必须重写,有点像Thread中的void run()方法。给AsyncTask指定的第一个参数类型就是它的参数类型。虽然这个方法只有一个参数类型,但参数个数是不限制的,当需要传入不同类型的多个参数时,大可以把Params直接指定为Object!从名称也可以看出,方法1就是后台执行的任务,在单独的线程中执行,所有费时的任务一股脑塞到这个方法里吧!值得注意的是,它的返回值类型就是给AsyncTask指定的第二个参数类型。

方法2是用来更新进度的,在UI线程执行,可以用来更新进度条的指数,所以通常给AsyncTask指定的第二个参数类型是Integer型。

方法3是后台任务完成后再被调用的,在UI线程中执行。它的参数类型是给AsyncTask指定的第三个参数类型,于是不妨大胆猜测一下,给它传入的参数就是方法1的返回值。有兴趣的朋友可以写个Demo验证一下。

还有一个方法不得不提:

方法0:void onPreExecute()

没错,这个方法是在开始后台任务前被调用的,同样在UI线程中执行。

可以看到,这些方法中只有方法1是在单独开辟的线程中执行的,也只有方法1是必须在子类中被实现的,其他方法可以根据需要重写。下面是从android reference中扒下的一个小例子,简单示范AsyncTask的使用:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}

protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}

protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}

子类写好后,可以在UI线程中这样来使用:


new DownloadFilesTask().execute(url1, url2, url3);


这样就大功告成啦!AsyncTask也具有一些自己的特点,如过程可控,可以随时取消。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: