AsyncTask 工作原理及线程池

来源:互联网 发布:变声软件哪个好 编辑:程序博客网 时间:2024/06/05 03:38

概要

在 android 中,线程通常为主线程和子线程,前者主要处理和界面相关的事情,而子线程主要用于耗时操作。 android 中的线程主要有 Thread、AsyncTask、IntentService 和 HandlerThread 。

AsyncTask、IntentService 和 HandlerThread 的底层实现都是线程,但都有特殊的表现形式,各有优缺点。 AsyncTask 封装了 线程池 和 Handler ,主要用于子线程更新UI;HandlerThread 是一种具有消息循环的线程,内部可以使用 Handler ; IntentService 是一个服务,内部采用 HandlerThread 执行任务,它类似一个后台线程,但是一个服务,不容易被杀死。

我们主要看AsyncTask

AsyncTask首次引入时,异步任务是在一个独立的线程中顺序地执行,也就是说一次只能执行一个任务,不能并行地执行,从1.6开始,AsyncTask中引入了线程池,支持同时执行5个异步任务,也就是说同时只能有5个线程运行,超过的线程只能等待,等待前面的线程某个执行完了才被调度和运行。换句话说,如果一个进程中的AsyncTask实例个数超过5个。那么假如前5个都运行很长时间的话,那么第6个只能等待机会了。

AsyncTask 是一个抽象的泛型类,有 Params, Progress, Result 三个泛型参数,分别表示参数类型、后台任务执行进度类型、后台任务返回结果类型。如果不需要具体的参数,可用 Void 代替。

public abstract class AsyncTask<Params, Progress, Result> {}
核心方法如下:
onPreExecute(): 这个方法是在执行异步任务之前的时候执行,并且是在UI Thread当中执行的,通常我们在这个方法里做一些UI控件的初始化的操作,例如弹出要给ProgressDialog
doInBackground(Params... params): 在onPreExecute()方法执行完之后,会马上执行这个方法,这个方法就是来处理异步任务的方法,Android操作系统会在后台的线程池当中开启一个worker thread来执行我们的这个方法,所以这个方法是在worker thread当中执行的,这个方法执行完之后就可以将我们的执行结果发送给我们的最后一个 onPostExecute 方法,在这个方法里,我们可以从网络当中获取数据等一些耗时的操作
onProgressUpdate(Progess... values): 这个方法也是在UI Thread当中执行的,我们在异步任务执行的时候,有时候需要将执行的进度返回给我们的UI界面,例如下载一张网络图片,我们需要时刻显示其下载的进度,就可以使用这个方法来更新我们的进度。这个方法在调用之前,我们需要在 doInBackground 方法中调用一个 publishProgress(Progress) 的方法来将我们的进度时时刻刻传递给 onProgressUpdate 方法来更新
onPostExecute(Result... result): 当我们的异步任务执行完之后,就会将结果返回给这个方法,这个方法也是在UI Thread当中调用的,我们可以将返回的结果显示在UI控件上

使用时注意事项:

AsyncTask 必须在主线程中加载
AsyncTask 的对象必须在主线程中创建
execute 方法必须在UI线程中调用
不要在程序中直接调用 上述和新方法
一个 AsyncTask 对象只能调用一次 execute 方法
AsyncTask 在 android3.0后 ,用一个线程串行执行任务。

使用方法如下

  class MyTask extends AsyncTask<String, Integer, String> {        @Override        protected String doInBackground(String... params) {            //执行异步任务            int n = 10;            //调用publishProgress公布进度,最后onProgressUpdate方法将被执行            publishProgress(n);            return null;        }        @Override        protected void onPostExecute(String result) {            //更新UI,显示结果        }        @Override        protected void onProgressUpdate(Integer... values) {            //更新进度信息        }    }
不要忘记

new MyTask().execute();//执行任务