android 多线程异步类asynctask 浅析

来源:互联网 发布:华宇软件股票 编辑:程序博客网 时间:2024/05/17 08:51

android 因为要遵守单线程模型必须在UI线程中更新UI,但是一些耗时的操作又不能放在UI线程中,以免引起UI线程阻塞从而导致的响应慢或者UI显示慢等问题,就需要

把这些耗时的操作放在单独的线程中去操作,这样就必然会经常遇见多线程开发的问题。android 提供了两种常用的线程间操作的方式:

一,handler & Thread &message

二,asynctask

今天我们重点来看一下asynctask这个android提供给我们的轻量级的异步类

asynctask正如类名一样这是一个异步任务类,参考android的文档说明,AsyncTask使能够适当和容易使用UI线程。这个类允许我们在UI主线程执行后台的操作

以及发布更新进度而不必通过handler和Thread类。

asynctask被设计成一个助手类让我们不必去通过handler&thread的框架完成后台操作,其实asynctask是对handler&thread的包装来实现的。asynctast设计的本意就是用来

执行短时间的操作,一般最多几秒钟时间。如果你要保持一个长时间的线程运行操作那么强烈建议你通过android提供的各种不同的接口实现,比如java.util.concurrent/Executor/

ThreadPoolExecutor/FutureTask.


asynctask类 AsyncTask<Params, Progress, Result>具有三个通用类型的参数:

  • Params 启动任务执行的输入参数,比如HTTP请求的URL。
  • Progress 后台任务执行的百分比。
  • Result 后台执行任务最终返回的结果,比如String。

用法:

asynctask本身是一个abstract的,我们必须通过继承这个类的子类来实现。子类至少要重写一个函数doInBackground,但是我们通常还要重写另外一个接口onPostExecute

下面是一个实现子类的例子:

* private class DownloadFilesTask extends AsyncTask&lt;URL, Integer, Long&gt; {
 *     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);就可以执行后台操作。


执行步骤:

一旦后台任务执行一般都经过下面四个步骤,

1,onPreExecute

这个函数在任务执行前在UI主线程中被调用,一般是执行对任务的设置工作,比如显示一个进度条给用户。

2,doInBackground

这个函数在onpreExecute执行完成后立即被后台线程执行去处理一些耗时的操作。异步任务传递的参数也被传递到这里,当后台任务处理完成后也将在这里返回处理的结果。

另外,虽然这个函数的执行是在子线程中的,但是我们一般在这个函数中通过publishProgress来不断的更新处理的进度。

3,onProgressUpdate

这个函数会在执行publishProgress后会自动调用onProgressUpdate更新UI线程中的值也就是更新进度条的进度。

4,onPostExecute

这个函数在后台任务完成后被调用,而且doInBackground的返回值会作为这个参数传入到这个函数。


删除后台任务:

一个后台任务可以随时通过cancel()函数来删除。这个删除的动作完成后会在后面调用isCancelled时返回true。执行这个函数后,onCancelled会在doInBackground返回后

被调用而不再调用onPostExecute。为了能够及时删除任务,我们应该在doInBackground中不停的检测isCancelled,如果可以的话比如说在一个循环中不停的检测isCancelled。


asynctask使用必须遵循以下规则:

1,自从你android 4.1开始asynctast 类必须在UI线程中加载。

2,必须在Ui主线程中实例化asynctask

3,execute方法必须在UI线程中调用

4,不能手动调用onPreExecute   doInBackground  onProgressUpdate    onPostExecute这几个方法

5,asynctask实例化后只能被执行一次,否则将会抛出异常





0 0
原创粉丝点击