AsyncTask的基本介绍

来源:互联网 发布:linux 修改用户权限组 编辑:程序博客网 时间:2024/06/04 14:21

一.基本介绍

我们都知道不能在主线程去更新UI,否则可能会引起ANR。所以我们一般会另开线程去执行耗时的操作,然后再 通过Handler去更新UI。不过,除了这个方法之外还可以用AsyncTask去实现相同的功能,AsyncTask能将这些耗时的操作通过后台线程去执行,执行完成后将结果在UI线程中去更新UI。

几个基本方法的简单介绍:onPreExecute():在doInbackground()之前被调用,做一些初始化的操作。doInBackground(Params...params):重写这个方法,将要在后台执行的操作放在这个方法里面,在这个方法中能调用publishProgress()去更新UI.onCancelled():如果实现了这个方法,那么将在doInBackground(Params...params)执行完成后调用这个方法,此时任务将被取消。onPostExecute(Result result):如果任务没有被取消,那么执行完 doInBackground(Params...params)之后将会调用这个方法,并把 doInBackground(Params...params)执行结果作为参数传递给这个方法。publishProgress():当在 doInBackground(Params...params)调用了这个方法之后,在后台任务还在执行的过程中可以一边去更新UI。每次调用这个方法,如果任务没被取消,那么都会去调用 onProgressUpdate()。onProgressUpdate():重写这个方法,实现更新UI操作。

二.简单使用

  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");                 }         }

这是官网的一个例子,一般是写一个内部类继承AsyncTask,而不是在程序中直接调用onPreExecute()等方法。当要执行上述的下载任务时,必须在主线程中创建AsyncTask对象,并在主线程中执行execte方法。这里需要注意的是一个AsyncTask对象只能执行一次,即只能调用一次execute方法。

为什么要将AsyncTask实例设计成只能够执行一次呢?这个说到底是出于线程安全的考虑,如果一个任务同时被执行,此时就可能
造成混乱,因为并行模式时各线程间是无序执行的。

三.工作原理

AsyncTask底层实现是线程池和Handler。在AsyncTask中维持了两个线程池(SerialExecutor和THREAD_POOL_EXECUTOR)和一个Handler(InternalHandler),其中线程池SerialExecutor用于任务的排队,线程池THREAD_POOL_EXECUTOR用于执行任务,而InternalHandler负责将执行环境从线程池切换到主线程。

0 0
原创粉丝点击