Android AsyncTask 从源码角度解析其原理和用法

AsyncTask 在线查看源码地址:AsyncTask简介:

众所周知知道,Android UI是线程不安全的,如果要想在子线程中更新UI操作,必须使用Android的异步消息处理机制。当然我们自己可以实现一个Handler+Message消息处理机制来在子线程中更新UI操作。有时候觉得自己写这个异步消息处理机制很麻烦有木有??不过庆幸的是,Android 给我们实现了这么一套异步消息处理机制,我们直接拿来用就是了,从而 AsyncTask就诞生了。AsyncTask用于Android的异步消息 处理机制,来实现子线程和UI线程间的一些通信。

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 calledif (isCancelled()) break;}return totalSize;}protected void onProgressUpdate(Integer… progress) {setProgressPercent(progress[0]);}protected void onPostExecute(Long result) {showDialog("Downloaded " + result + " bytes");} }

执行操作如下:

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

由于AsyncTask是个抽象类,如果我们要使用它,必须写个子类去继承AsyncTask,在继承时我们可以为AsyncTask类指定三个泛型参数,这三个参数的用途如下:

1.Params:

用于doInBackground()后台执行任务的参数。

2.Progress:

用于后台执行任务进度的更新。

3.Result:

当任务执行完毕时,需要对结果进行返回,用于保存执行结果。

AsyncTask执行的步骤如下:

:在UI线程中执行,通常用于异步任务执行之前,初始化一些数据,比如:初始化进度条等。

:在后台线程中执行,一般耗时任务都在这个方法里面实现,当然在这个方法里面我们必须返回执行结果,用于步骤,将异步任务结果发布到UI线程中。在这个方法里我们可以选择性的调用方法,用于将异步任务执行进度信息发布到UI线程中。

:在UI线程中执行,用于对后台任务执行进度信息的更新。只有在方法中调用了方法,才能拿到后台任务执行进度信息。

:在UI线程中执行,用于获取后台任务执行的结果。

AsyncTask的特征:

1.异步任务的实例必须在UI线程中创建2.execute(Params… params)方法执行必须在UI线程中调用

3.一个异步任务只能执行一个,不然会抛出“Cannot execute task:the task is already running.”异常。

4.不能在做更新UI的操作。

5.不要手动的去调用onPreExecute(),doInBackground(Params… params),onProgressUpdate(Progress… values),onPostExecute(Result result) 这几个方法。

解析以上5点Why??等我们分析完整个源码再来回答这个问题吧。

AsycnTask的源码分析:

1.execute(params)

public final AsyncTask<Params, Progress, Result> execute(Params… params) {return executeOnExecutor(sDefaultExecutor, params);}

这个方法只执行了一行代码,就是调用executeOnExecutor(sDefaultExecutor, params) 方法。进去看看:

public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,Params… params) {if (mStatus != Status.PENDING) {switch (mStatus) {case RUNNING:throw new IllegalStateException("Cannot execute task:"+ " the task is already running.");case FINISHED:throw new IllegalStateException("Cannot execute task:"+ " the task has already been executed "+ "(a task can be executed only once)");}}mStatus = Status.RUNNING;onPreExecute();mWorker.mParams = params;exec.execute(mFuture);return this;}我们可以看到这里有个状态值的判断,就是枚举类型Status了,看看代码:

public enum Status {/*** Indicates that the task has not been executed yet.*/PENDING,/*** Indicates that the task is running.*/RUNNING,/*** Indicates that {@link AsyncTask#onPostExecute} has finished.*/FINISHED,}三种状态用来标志当前的异步任务处于那种状态。当前任务的初始状态是PENDING:为待执行状态。

天下没有不散的宴席,也许这人间真的只有朦朦胧胧才是真。

Android AsyncTask 从源码角度解析其原理和用法

相关文章:

你感兴趣的文章:

标签云: