Android中AsyncTask使用详解_asynctack-程序员宅基地

技术标签: Android中AsyncTask使用详  Android  

在Android中我们可以通过Thread+Handler实现多线程通信,一种经典的使用场景是:在新线程中进行耗时操作,当任务完成后通过Handler向主线程发送Message,这样主线程的Handler在收到该Message之后就可以进行更新UI的操作。上述场景中需要分别在Thread和Handler中编写代码逻辑,为了使得代码更加统一,我们可以使用AsyncTask类。

AsyncTask是Android提供的一个助手类,它对Thread和Handler进行了封装,方便我们使用。Android之所以提供AsyncTask这个类,就是为了方便我们在后台线程中执行操作,然后将结果发送给主线程,从而在主线程中进行UI更新等操作。在使用AsyncTask时,我们无需关注Thread和Handler,AsyncTask内部会对其进行管理,这样我们就只需要关注于我们的业务逻辑即可。

AsyncTask有四个重要的回调方法,分别是:onPreExecute、doInBackground, onProgressUpdate 和 onPostExecute。这四个方法会在AsyncTask的不同时期进行自动调用,我们只需要实现这几个方法的内部逻辑即可。这四个方法的一些参数和返回值都是基于泛型的,而且泛型的类型还不一样,所以在AsyncTask的使用中会遇到三种泛型参数:Params, Progress 和 Result,如下图所示: 
这里写图片描述

  • Params表示用于AsyncTask执行任务的参数的类型
  • Progress表示在后台线程处理的过程中,可以阶段性地发布结果的数据类型
  • Result表示任务全部完成后所返回的数据类型

我们通过调用AsyncTask的execute()方法传入参数并执行任务,然后AsyncTask会依次调用以下四个方法:

  • onPreExecute 
    该方法的签名如下所示: 
    这里写图片描述 
    该方法有MainThread注解,表示该方法是运行在主线程中的。在AsyncTask执行了execute()方法后就会在UI线程上执行onPreExecute()方法,该方法在task真正执行前运行,我们通常可以在该方法中显示一个进度条,从而告知用户后台任务即将开始。

  • doInBackground 
    该方法的签名如下所示: 
    这里写图片描述 
    该方法有WorkerThread注解,表示该方法是运行在单独的工作线程中的,而不是运行在主线程中。doInBackground会在onPreExecute()方法执行完成后立即执行,该方法用于在工作线程中执行耗时任务,我们可以在该方法中编写我们需要在后台线程中运行的逻辑代码,由于是运行在工作线程中,所以该方法不会阻塞UI线程。该方法接收Params泛型参数,参数params是Params类型的不定长数组,该方法的返回值是Result泛型,由于doInBackgroud是抽象方法,我们在使用AsyncTask时必须重写该方法。在doInBackground中执行的任务可能要分解为好多步骤,每完成一步我们就可以通过调用AsyncTask的publishProgress(Progress…)将阶段性的处理结果发布出去,阶段性处理结果是Progress泛型类型。当调用了publishProgress方法后,处理结果会被传递到UI线程中,并在UI线程中回调onProgressUpdate方法,下面会详细介绍。根据我们的具体需要,我们可以在doInBackground中不调用publishProgress方法,当然也可以在该方法中多次调用publishProgress方法。doInBackgroud方法的返回值表示后台线程完成任务之后的结果。

  • onProgressUpdate 
    上面我们知道,当我们在doInBackground中调用publishProgress(Progress…)方法后,就会在UI线程上回调onProgressUpdate方法,该方法的方法签名如下所示: 
    这里写图片描述 
    该方法也具有MainThread注解,表示该方法是在主线程上被调用的,且传入的参数是Progress泛型定义的不定长数组。如果在doInBackground中多次调用了publishProgress方法,那么主线程就会多次回调onProgressUpdate方法。

  • onPostExecute 
    该方法的签名如下所示: 
    这里写图片描述 
    该方法也具有MainThread注解,表示该方法是在主线程中被调用的。当doInBackgroud方法执行完毕后,就表示任务完成了,doInBackgroud方法的返回值就会作为参数在主线程中传入到onPostExecute方法中,这样就可以在主线程中根据任务的执行结果更新UI。

下面我们就以下载多个文件的示例演示AsyncTask的使用过程。

布局文件如下所示:

<code class="hljs perl has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><RelativeLayout xmlns:android=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/apk/res/android"</span>
    xmlns:tools=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/tools"</span>
    android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"match_parent"</span>
    android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"match_parent"</span>
    android:paddingLeft=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@dimen</span>/activity_horizontal_margin"</span>
    android:paddingRight=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@dimen</span>/activity_horizontal_margin"</span>
    android:paddingTop=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@dimen</span>/activity_vertical_margin"</span>
    android:paddingBottom=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@dimen</span>/activity_vertical_margin"</span>
    tools:context=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">".MainActivity"</span>>

    <Button android:id=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@+</span>id/btnDownload"</span>
        android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"match_parent"</span>
        android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span>
        android:onClick=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"onClick"</span>
        android:text=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"开始下载"</span> />

    <TextView android:id=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@+</span>id/textView"</span>
        android:layout_below=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@id</span>/btnDownload"</span>
        android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"match_parent"</span>
        android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span> />

<<span class="hljs-regexp" style="color: rgb(0, 136, 0); box-sizing: border-box;">/RelativeLayout></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li></ul>

界面上有一个“开始下载”的按钮,点击该按钮即可通过AsyncTask下载多个文件,对应的Java代码如下所示:

<code class="hljs axapta has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;">package com.ispring.asynctask;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">MainActivity</span> <span class="hljs-inheritance" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span></span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Activity</span> <span class="hljs-inheritance" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">implements</span></span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Button</span>.<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">OnClickListener</span> {</span>

    TextView textView = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
    Button btnDownload = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;

    @Override
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onCreate(Bundle savedInstanceState) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView)findViewById(R.id.textView);
        btnDownload = (Button)findViewById(R.id.btnDownload);
        Log.i(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"iSpring"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"MainActivity -> onCreate, Thread name: "</span> + Thread.currentThread().getName());
    }

    @Override
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onClick(View v) {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//要下载的文件地址</span>
        String[] urls = {
                <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47115879"</span>,
                <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47180325"</span>,
                <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47300819"</span>,
                <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47320407"</span>,
                <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47622705"</span>
        };

        DownloadTask downloadTask = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> DownloadTask();
        downloadTask.execute(urls);
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//public abstract class AsyncTask<Params, Progress, Result></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//在此例中,Params泛型是String类型,Progress泛型是Object类型,Result泛型是Long类型</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">DownloadTask</span> <span class="hljs-inheritance" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">extends</span></span> <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">AsyncTask</span><<span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">String</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Object</span>, <span class="hljs-title" style="box-sizing: border-box; color: rgb(102, 0, 102);">Long</span>> {</span>
        @Override
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onPreExecute() {
            Log.i(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"iSpring"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"DownloadTask -> onPreExecute, Thread name: "</span> + Thread.currentThread().getName());
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onPreExecute();
            btnDownload.setEnabled(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">false</span>);
            textView.setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"开始下载..."</span>);
        }

        @Override
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> Long doInBackground(String... params) {
            Log.i(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"iSpring"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"DownloadTask -> doInBackground, Thread name: "</span> + Thread.currentThread().getName());
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//totalByte表示所有下载的文件的总字节数</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">long</span> totalByte = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//params是一个String数组</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>(String url: params){
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//遍历Url数组,依次下载对应的文件</span>
                Object[] result = downloadSingleFile(url);
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> byteCount = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>)result[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];
                totalByte += byteCount;
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//在下载完一个文件之后,我们就把阶段性的处理结果发布出去</span>
                publishProgress(result);
                <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//如果AsyncTask被调用了cancel()方法,那么任务取消,跳出for循环</span>
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(isCancelled()){
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">break</span>;
                }
            }
            <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将总共下载的字节数作为结果返回</span>
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> totalByte;
        }

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//下载文件后返回一个Object数组:下载文件的字节数以及下载的博客的名字</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> Object[] downloadSingleFile(String <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>){
            Object[] result = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> Object[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>];
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> byteCount = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
            String blogName = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">""</span>;
            HttpURLConnection conn = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span>{
                URL url = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> URL(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">str</span>);
                conn = (HttpURLConnection)url.openConnection();
                InputStream is = conn.getInputStream();
                ByteArrayOutputStream baos = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> ByteArrayOutputStream();
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] buf = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1024</span>];
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> length = -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> ((length = is.read(buf)) != -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>) {
                    baos.write(buf, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, length);
                    byteCount += length;
                }
                String respone = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> String(baos.toByteArray(), <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"utf-8"</span>);
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> startIndex = respone.indexOf(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"<title>"</span>);
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(startIndex > <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>){
                    startIndex += <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">7</span>;
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> endIndex = respone.indexOf(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"</title>"</span>);
                    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(endIndex > startIndex){
                        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//解析出博客中的标题</span>
                        blogName = respone.substring(startIndex, endIndex);
                    }
                }
            }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span>(MalformedURLException e){
                e.printStackTrace();
            }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span>(IOException e){
                e.printStackTrace();
            }<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">finally</span> {
                <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(conn != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>){
                    conn.disconnect();
                }
            }
            result[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>] = byteCount;
            result[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>] = blogName;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> result;
        }

        @Override
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onProgressUpdate(Object... values) {
            Log.i(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"iSpring"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"DownloadTask -> onProgressUpdate, Thread name: "</span> + Thread.currentThread().getName());
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onProgressUpdate(values);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> byteCount = (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>)values[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];
            String blogName = (String)values[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>];
            String text = textView.getText().toString();
            text += <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\n博客《"</span> + blogName + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"》下载完成,共"</span> + byteCount + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"字节"</span>;
            textView.setText(text);
        }

        @Override
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onPostExecute(Long aLong) {
            Log.i(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"iSpring"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"DownloadTask -> onPostExecute, Thread name: "</span> + Thread.currentThread().getName());
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onPostExecute(aLong);
            String text = textView.getText().toString();
            text += <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"\n全部下载完成,总共下载了"</span> + aLong + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"个字节"</span>;
            textView.setText(text);
            btnDownload.setEnabled(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);
        }

        @Override
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">protected</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> onCancelled() {
            Log.i(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"iSpring"</span>, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"DownloadTask -> onCancelled, Thread name: "</span> + Thread.currentThread().getName());
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">super</span>.onCancelled();
            textView.setText(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"取消下载"</span>);
            btnDownload.setEnabled(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>);
        }
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</li><li style="box-sizing: border-box; padding: 0px 5px;">113</li><li style="box-sizing: border-box; padding: 0px 5px;">114</li><li style="box-sizing: border-box; padding: 0px 5px;">115</li><li style="box-sizing: border-box; padding: 0px 5px;">116</li><li style="box-sizing: border-box; padding: 0px 5px;">117</li><li style="box-sizing: border-box; padding: 0px 5px;">118</li><li style="box-sizing: border-box; padding: 0px 5px;">119</li><li style="box-sizing: border-box; padding: 0px 5px;">120</li><li style="box-sizing: border-box; padding: 0px 5px;">121</li><li style="box-sizing: border-box; padding: 0px 5px;">122</li><li style="box-sizing: border-box; padding: 0px 5px;">123</li><li style="box-sizing: border-box; padding: 0px 5px;">124</li><li style="box-sizing: border-box; padding: 0px 5px;">125</li><li style="box-sizing: border-box; padding: 0px 5px;">126</li><li style="box-sizing: border-box; padding: 0px 5px;">127</li><li style="box-sizing: border-box; padding: 0px 5px;">128</li><li style="box-sizing: border-box; padding: 0px 5px;">129</li><li style="box-sizing: border-box; padding: 0px 5px;">130</li><li style="box-sizing: border-box; padding: 0px 5px;">131</li><li style="box-sizing: border-box; padding: 0px 5px;">132</li><li style="box-sizing: border-box; padding: 0px 5px;">133</li><li style="box-sizing: border-box; padding: 0px 5px;">134</li><li style="box-sizing: border-box; padding: 0px 5px;">135</li><li style="box-sizing: border-box; padding: 0px 5px;">136</li><li style="box-sizing: border-box; padding: 0px 5px;">137</li><li style="box-sizing: border-box; padding: 0px 5px;">138</li><li style="box-sizing: border-box; padding: 0px 5px;">139</li><li style="box-sizing: border-box; padding: 0px 5px;">140</li><li style="box-sizing: border-box; padding: 0px 5px;">141</li><li style="box-sizing: border-box; padding: 0px 5px;">142</li><li style="box-sizing: border-box; padding: 0px 5px;">143</li><li style="box-sizing: border-box; padding: 0px 5px;">144</li><li style="box-sizing: border-box; padding: 0px 5px;">145</li><li style="box-sizing: border-box; padding: 0px 5px;">146</li><li style="box-sizing: border-box; padding: 0px 5px;">147</li><li style="box-sizing: border-box; padding: 0px 5px;">148</li><li style="box-sizing: border-box; padding: 0px 5px;">149</li><li style="box-sizing: border-box; padding: 0px 5px;">150</li><li style="box-sizing: border-box; padding: 0px 5px;">151</li></ul>

点击下载按钮后,界面如下所示: 
这里写图片描述

控制台输出如下所示: 
这里写图片描述

下面对以上代码进行一下说明。

  1. 我们在MainActivity中定义了内部类DownloadTask,DownloadTask继承自AsyncTask,在该例中,Params泛型是String类型,Progress泛型是Object类型,Result泛型是Long类型。

  2. 我们定义了一个Url字符串数组,将该数组传递给AsyncTask的execute方法,用于异步执行task。

  3. 在执行了downloadTask.execute(urls)之后,AsyncTask会自动回调onPreExecute方法,在该方法中我们将textView设置为“开始下载…”几个字,告知用户即将执行下载操作。通过控制台输出我们也可以看出该方法是在主线程中执行的。

  4. 在执行了onPreExecute方法之后,AsyncTask会回调doInBackground方法,该方法中的输入参数是String类型的不定长数组,此处的String就对应着Params泛型类型,我们在该方法中遍历Url数组,依次下载对应的文件,当我们下载完一个文件,就相当于我们阶段性地完成了一部分任务,我们就通过调用publishProgress方法将阶段性处理结果发布出去。在此例中我们将阶段性的处理结果定义为Object类型,即Progress泛型类型。通过控制台输出我们可以看出doInBackground方法是运行在新的工作线程”AsyncTask #1”中的,AsyncTask的工作线程都是以”AsyncTask #”然后加上数字作为名字。当所有文件下载完成后,我们就可以通过totalSize返回所有下载的字节数,返回值类型为Long,对应着AsyncTask中的Result泛型类型。

  5. 在doInBackground方法中,每当下载完一个文件,我们就会调用publishProgress方法发布阶段性结果,之后AsyncTask会回调onProgressUpdate方法,在此例中,onProgressUpdate的参数为Object类型,对应着AsyncTask中的Progress泛型类型。通过控制台输出我们可以发现,该方法是在主线程中调用的,在该方法中我们会通过textView更新UI,告知用户哪个文件下载完成了,这样用户体验相对友好。

  6. 在整个doInBackground方法执行完毕后,AsyncTask就会回调onPostExecute方法,在该方法中我们再次通过textView更新UI告知用户全部下载任务完成了。

  7. 在通过execute方法执行了异步任务之后,可以通过AsyncTask的cancel方法取消任务,取消任务后AsyncTask会回调onCancelled方法,这样不会再调用onPostExecute方法。

在使用Android的过程中,有以下几点需要注意:

  • AsyncTask的实例必须在主线程中创建。

  • AsyncTask的execute方法必须在主线程中调用。

  • onPreExecute()、onPostExecute(Result),、doInBackground(Params…) 和 onProgressUpdate(Progress…)这四个方法都是回调方法,Android会自动调用,我们不应自己调用。

  • 对于一个AsyncTack的实例,只能执行一次execute方法,在该实例上第二次执行execute方法时就会抛出异常。

通过上面的示例,大家应该熟悉了AsyncTask的使用流程。我们上面提到,对于某个AsyncTask实例,只能执行一次execute方法,如果我们想并行地执行多个任务怎么办呢?我们可以考虑实例化多个AsyncTask实例,然后分别调用各个实例的execute方法,为了探究效果,我们将代码更改如下所示:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClick</span>(View v) {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//要下载的文件地址</span>
        String[] urls = {
                <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47115879"</span>,
                <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47180325"</span>,
                <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47300819"</span>,
                <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47320407"</span>,
                <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47622705"</span>
        };

        DownloadTask downloadTask1 = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> DownloadTask();
        downloadTask1.execute(urls);

        DownloadTask downloadTask2 = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> DownloadTask();
        downloadTask2.execute(urls);
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>

在单击了按钮之后,我们实例化了两个DownloadTask,并分别执行其execute方法,运行后界面如下所示: 
这里写图片描述

控制台输出如下所示: 
这里写图片描述

我们观察一下控制台的输出结果,可以发现对于downloadTask1,doInBackground方法是运行在线程“AsyncTask #1”中的;对于downloadTask2,doInBackground方法是运行在线程”AsyncTask #2”中的,此时我们可能会认为太好了,两个AsyncTask实例分别在不同的线程中运行,实现了并行处理。此处真的是并行运行的吗?

我们自己观察控制台输出就可以发现,downloadTask1的doInBackground方法执行后,下载了五个文件,并五次触发了onProgressUpdate,在这之后才执行downloadTask2的doInBackground方法。我们对比上面的GIF图也可以发现,在downloadTask1按照顺序下载完五篇文章之后,downloadTask2才开始按照顺序下载五篇文章。综上所述,我们可以知道,默认情况下如果创建了AsyncTask创建了多个实例,并同时执行实例的各个execute方法,那么这些实例的execute方法并不是并行执行的,是串行执行的,即在第一个实例的doInBackground完成任务后,第二个实例的doInBackgroud方法才会开始执行,然后再执行第三个实例的doInBackground方法… 那么你可能会问,不对啊,上面downloadTask1是运行在”AsyncTask #1”线程中的,downloadTask2是运行在”AsyncTask #2”线程中的,这明明是两个线程啊!其实AsyncTask为downloadTask1开辟了名为”AsyncTask #1”的工作线程,在其完成了任务之后可能就销毁了,然后AsyncTask又为downloadTask2开辟了名为”AsyncTask #2”的工作线程。

AsyncTask在最早的版本中用一个单一的后台线程串行执行多个AsyncTask实例的任务,从Android 1.6(DONUT)开始,AsyncTask用线程池并行执行异步任务,但是从Android 3.0(HONEYCOMB)开始为了避免并行执行导致的常见错误,AsyncTask又开始默认用单线程作为工作线程处理多个任务。

从Android 3.0开始AsyncTask增加了executeOnExecutor方法,用该方法可以让AsyncTask并行处理任务,该方法的方法签名如下所示:

<code class="hljs oxygene has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> AsyncTask<<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Params</span>, Progress, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Result</span>> executeOnExecutor (Executor exec, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">Params</span>... <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">params</span>)</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

第一个参数表示exec是一个Executor对象,为了让AsyncTask并行处理任务,通常情况下我们此处传入AsyncTask.THREAD_POOL_EXECUTOR即可,AsyncTask.THREAD_POOL_EXECUTOR是AsyncTask中内置的一个线程池对象,当然我们也可以传入我们自己实例化的线程池对象。第二个参数params表示的是要执行的任务的参数。

通过executeOnExecutor方法并行执行任务的示例代码如下所示:

<code class="hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">onClick</span>(View v) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(Build.VERSION.SDK_INT >= <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">11</span>){
            String[] urls = {
                    <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47115879"</span>,
                    <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47180325"</span>,
                    <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47300819"</span>,
                    <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47320407"</span>,
                    <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://blog.csdn.net/iispring/article/details/47622705"</span>
            };

            DownloadTask downloadTask1 = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> DownloadTask();
            downloadTask1.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, urls);

            DownloadTask downloadTask2 = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> DownloadTask();
            downloadTask2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, urls);
        }
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li></ul>

我们实例化了两个DownloadTask的实例,然后执行了这两个实例的executeOnExecutor方法,并将AsyncTask.THREAD_POOL_EXECUTOR作为Executor传入,二者都接收同样的Url数组作为任务执行的参数。

点击下载按钮后,运行完的界面如下所示: 
这里写图片描述

控制台输出如下所示: 
这里写图片描述

通过控制台的输出结果我们可以看到,在downloadTask1执行了doInBackground方法后,downloadTask2也立即执行了doInBackground方法。并且通过程序运行完的UI界面可以看到在一个DownloadTask实例下载了一篇文章之后,另一个DownloadTask实例也立即下载了一篇文章,两个DownloadTask实例交叉按顺序下载文件,可以看出这两个AsyncTask的实例是并行执行的。

后面会写文章讲一下AsyncTask的源码实现原理,希望本文对大家使用AsyncTask的使用有所帮助!

相关阅读: 
我的Android博文整理汇总 
Android中Handler的使用 
Android新线程中更新主线程UI中的View方法汇总

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_17007915/article/details/50683835

智能推荐

Lingo (Spring Remoting) : Passing client credentials to the server-程序员宅基地

文章浏览阅读103次。http://www.jroller.com/sjivan/entry/lingo_spring_remoting_passing_clientLingo (Spring Remoting) : Passing client credentials to the serverSpring Remoting allows you to export a service interface w..._clientcontextholder

Codova 创建项目,引用jar提示java.lang.VerifyError_codova aar-程序员宅基地

文章浏览阅读307次。背景说明:Android原生的开发包是直接通过gradle加载aar使用,由于客户需要模块的cordova插件,于是只能引用aar解压出来的jar包,通过cordova创建项目,指定Android平台,引入插件,然后编译安装(此时创建的项目可以通过AndroidStudio打开)Cordova创建的项目 在Android6.0上跑报如下错误,字面上看java编译器拒绝编译这个类Re..._codova aar

L1-023 输出GPLT-程序员宅基地

文章浏览阅读487次,点赞13次,收藏10次。给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序,按这样的顺序输出,并忽略其它字符。当然,四种字符(不区分大小写)的个数不一定是一样多的,若某种字符已经输出完,则余下的字符仍按GPLT的顺序打印,直到所有字符都被输出。_l1-023 输出gplt

element-ui中el-pagination分页组件,切换每页显示数量时,有时候数据不显示或获取到的数据为空;只想触发size-change事件不触发current-change事件_element-ui 分页展示数据 不全-程序员宅基地

文章浏览阅读1.3w次,点赞9次,收藏20次。element-ui中el-pagination分页组件使用注意事项切换每页显示数量时,有时候数据不显示或获取到的数据为空el-pagination组件只想触发size-change事件不触发current-change事件_element-ui 分页展示数据 不全

嵌入式面试题 C C++ 队列面试题总结-程序员宅基地

文章浏览阅读864次,点赞19次,收藏20次。你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!” />你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!更多资料点击此处获qu!!

Android热修复原理热修复框架对比和代码修复-程序员宅基地

文章浏览阅读750次,点赞26次,收藏20次。在Android应用开发中,热修复技术被越来越多的开发者所使用,也出现了很多热修复框架,比如:AndFix、Tinker、Dexposed和Nuwa等等。如果只是会这些热修复框架的使用那意义并不大,我们还需要了解它们的原理,这样不管热修复框架如何变化,只要基本原理不变,我们就可以很快的掌握它们。这一个系列不会对某些热修复框架源码进行解析,而是讲解热修复框架的通用原理。

随便推点

SM2259XT2量产工具下载方法,SM2259XT2硬盘开卡修复满血复活,SM2259XT2固件,SM2259XT2量产图文教程_sm2258xt量产工具下载-程序员宅基地

文章浏览阅读482次,点赞7次,收藏4次。​我这个固态是SM2259XT2和海力士HY3D-V7的搭配,就得从量产部落找这个组合的量产工具。_sm2258xt量产工具下载

【BSV无限可能】区块链的商业应用_bsv 跨链能力-程序员宅基地

文章浏览阅读491次。2023年2月在斯洛文尼亚的一个专属会场,nChain首席科学家Craig S. Wright博士举办了自己新一期的比特币大师班。比特币大师班课程是月度系列活动,旨在帮助参会者学习比特币的基本原理及其背后的技术知识。_bsv 跨链能力

2019校招前端笔试面试题_javaee为什么前端某个数据状态发生变化只发生在用户本地,不会影响到其他用户-程序员宅基地

文章浏览阅读1.6w次,点赞38次,收藏261次。前期概要:01你做的页面在哪些流览器测试过?这些浏览器的内核分别是什么?答案IE:trident内核Firefox:gecko内核Safari:webkit内核Opera:以前是presto内核,Opera现已改用Google Chrome的Blink内核Chrome:Blink(基于webkit,Google与Opera Software共同开发)02Javas..._javaee为什么前端某个数据状态发生变化只发生在用户本地,不会影响到其他用户

无线通信中的TD系统(TD-LTE)-程序员宅基地

文章浏览阅读850次。5G中的核心技术_td系统

Linux系统中最佳开源电子邮件服务器_linux邮件服务器有哪些-程序员宅基地

文章浏览阅读1.1k次,点赞27次,收藏20次。以上是Linux系统中备受推荐的开源电子邮件服务器,包括了Postfix、Exim、Dovecot、OpenSMTPD、Mailcow和iRedMail。每种邮件服务器都有其独特的特点和优势,适用于不同的部署场景和需求。希望本文的介绍能够帮助大家选择适合的最佳开源邮件服务器,并建立稳定、安全的邮件系统。更多Python学习内容:ipengtao.com点击下方“阅读原文”查看更多。_linux邮件服务器有哪些

a-select-程序员宅基地

文章浏览阅读712次。a-select支持搜索_a-select

推荐文章

热门文章

相关标签