AsyncTask生命周期

AsyncTask定义了三种泛型类型 Params,Progress和Result。
Params 启动任务执行的输入参数,比如HTTP请求的URL。
Progress 后台任务执行的百分比。
Result 后台执行任务最终返回的结果,比如String。

子类必须实现抽象方法doInBackground(Params… p) ,在此方法中实现任务的执行工作,比如连接网络获取数据等。通常还应该实现onPostExecute(Result r)方法,因为应用程序关心的结果在此方法中返回。需要注意的是AsyncTask一定要在主线程中创建实例。

AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,需要注意的是这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。在任务的执行过程中,这些方法被自动调用,运行过程,如下图所示:

附件: 89957709-388a-302c-90f2-2e965c46fa90.jpg 

onPreExecute() 当任务执行之前开始调用此方法,可以在这里显示进度对话框。

doInBackground(Params…) 此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。

onProgressUpdate(Progress…) 此方法在主线程执行,用于显示任务执行的进度。

onPostExecute(Result) 此方法在主线程执行,任务执行的结果作为此方法的参数返回
  1. package cn.com.chenzheng_java;  
  2.    
  3. import android.os.AsyncTask;  
  4. /** 
  5.  *  
  6.  * @author chenzheng_java 
  7.  * @description 异步任务AcyncTask示例 
  8.  *     
  9.  */  
  10. public class MyAsyncTask extends AsyncTask {  
  11.    
  12.  /** 
  13.  * 该方法由ui线程进行调用,用户可以在这里尽情的访问ui组件。 
  14.  * 很多时候,我们会在这里显示一个进度条啥的,以示后台正在 
  15.  * 执行某项功能。 
  16.  */  
  17.  @Override  
  18.  protected void onPreExecute() {  
  19.  super.onPreExecute();  
  20.  }  
  21.    
  22.  /** 
  23.  * 该方法由后台进程进行调用,进行主要的耗时的那些计算。 
  24.  * 该方法在onPreExecute方法之后进行调用。当然在执行过程中 
  25.  * 我们可以每隔多少秒就调用一次publishProgress方法,更新 
  26.  * 进度信息 
  27.  */  
  28.  @Override  
  29.  protected Object doInBackground(String... params) {  
  30.  return null;  
  31.  }  
  32.    
  33.    
  34.  /** 
  35.  * doInBackground中调用了publishProgress之后,ui线程就会 
  36.  * 调用该方法。你可以在这里动态的改变进度条的进度,让用户知道 
  37.  * 当前的进度。 
  38.  */  
  39.  @Override  
  40.  protected void onProgressUpdate(Integer... values) {  
  41.  super.onProgressUpdate(values);  
  42.  }  
  43.    
  44.  /** 
  45.  * 当doInBackground执行完毕之后,由ui线程调用。可以在这里 
  46.  * 返回我们计算的最终结果给用户。 
  47.  */  
  48.  @Override  
  49.  protected void onPostExecute(Object result) {  
  50.  super.onPostExecute(result);  
  51.  }  
  52. }  


使用AsyncTask的时候我们可以看到几个明显的缺陷和问题:

  • 主要针对UI线程;
  • 无法处理异常情况;
  • 线程池里面维护的线程数量过多(CORE_POOL_SIZE默认是5个);
所以针对以上弊端,我重写了该类,希望对大家有所帮助,另外如有不如意的地方,还请大家指正:
view plain
  1. package com.isomobile.toollib;  
  2.   
  3.   
  4. import android.content.Context;  
  5. import android.os.Handler;  
  6. import android.os.Message;  
  7. import android.os.Process;  
  8.   
  9. import java.util.concurrent.ThreadPoolExecutor;  
  10. import java.util.concurrent.TimeUnit;  
  11. import java.util.concurrent.BlockingQueue;  
  12. import java.util.concurrent.LinkedBlockingQueue;  
  13. import java.util.concurrent.ThreadFactory;  
  14. import java.util.concurrent.Callable;  
  15. import java.util.concurrent.FutureTask;  
  16. import java.util.concurrent.ExecutionException;  
  17. import java.util.concurrent.TimeoutException;  
  18. import java.util.concurrent.CancellationException;  
  19. import java.util.concurrent.atomic.AtomicInteger;  
  20.   
  21. /** 
  22.  * 

    UserTask是一个为了提高应用性能和能够处理各种异常的一个能运行在前后台的线程池框架.

     
  23.  *  
  24.  * 

    UserTask运行在后台,可以只处理后台数据,也可以将后台数据展现在前台UI界面上。 

  25.  * UserTask定义了3个泛型参数,分别是: ParamsProgress 和 Result 
  26.  *  
  27.  * 

    使用

     
  28.  * 

    1.在使用UserTask的时候,首先是实现一个继承它的类. 子类至少需要override 

  29.  * ({@link #onErrorHandle})和({@link #onTaskFinished}.)

     
  30.  *  
  31.  * 

    下面是创建子类的例子:

     
  32.  *  
  33.  * private final class DownloadTaskManager extends UserTask { 
  34.  *    protected void onErrorHandle(Context context, Exception error) { 
  35.  *        mLog.debug("onErrorHandle : " + error.getMessage()); 
  36.  *    } 
  37.  * 
  38.  *    protected void onTaskFinished(Context context, Boolean result) { 
  39.  *          
  40.  *    } 
  41.  * } 
  42.  *  
  43.  *  
  44.  * 接着需要在调用继承实现的子类对象的registerCallback方法里面去添加任务。 
  45.  *  
  46.  * final DownloadTaskManager manager = new DownloadTaskManager(); 
  47.  *       //final FileDownloader downloader = new FileDownloader(DownloadService.this); 
  48.  *       manager.registerCallback(new TaskCallback() { 
  49.  *           public Object call(UserTask task, Integer[] params) throws Exception { 
  50.  *                //需要后台的操作 
  51.  *          } 
  52.  *        }); 
  53.  *  
  54.  */  
  55. public abstract class UserTask {  
  56.       
  57.     /** The Constant CORE_POOL_SIZE. */  
  58.     private static final int CORE_POOL_SIZE = 2;  
  59.       
  60.     /** The Constant MAXIMUM_POOL_SIZE. */  
  61.     private static final int MAXIMUM_POOL_SIZE = 32;  
  62.       
  63.     /** The Constant KEEP_ALIVE. */  
  64.     private static final int KEEP_ALIVE = 15;  
  65.   
  66.     /** The Constant mWorkQueue. */  
  67.     private static final BlockingQueue mWorkQueue =  
  68.             new LinkedBlockingQueue(MAXIMUM_POOL_SIZE);  
  69.   
  70.     /** The Constant mThreadFactory. */  
  71.     private static final ThreadFactory mThreadFactory = new ThreadFactory() {  
  72.         private final AtomicInteger mCount = new AtomicInteger(1);  
  73.   
  74.         public Thread newThread(Runnable r) {  
  75.             return new Thread(r, "UserTask #" + mCount.getAndIncrement());  
  76.         }  
  77.     };  
  78.   
  79.     /** The Constant mExecutor. */  
  80.     private static final ThreadPoolExecutor mExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,  
  81.             MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, mWorkQueue, mThreadFactory);  
  82.   
  83.     /** The Constant MESSAGE_POST_RESULT. */  
  84.     private static final int MESSAGE_POST_RESULT = 0x1;  
  85.       
  86.     /** The Constant MESSAGE_POST_PROGRESS. */  
  87.     private static final int MESSAGE_POST_PROGRESS = 0x2;  
  88.       
  89.     /** The Constant MESSAGE_POST_CANCEL. */  
  90.     private static final int MESSAGE_POST_CANCEL = 0x3;  
  91.   
  92.     /** The Constant mHandler. */  
  93.     private static final InternalHandler mHandler = new InternalHandler();  
  94.   
  95.     /** The m worker. */  
  96.     private final WorkerRunnable mWorker;  
  97.       
  98.     /** The m future. */  
  99.     private final FutureTask mFuture;  
  100.   
  101.     /** The m status. */  
  102.     private volatile Status mStatus = Status.PENDING;  
  103.       
  104.     /** The m error. */  
  105.     protected Exception mError;  
  106.       
  107.       
  108.     /** The m callbask. */  
  109.     private TaskCallback mCallback;  
  110.       
  111.     private Context mContext;  
  112.       
  113.     /** 
  114.      * Indicates the current status of the task. Each status will be set only once 
  115.      * during the lifetime of a task. 
  116.      */  
  117.     public enum Status {  
  118.         /** 
  119.          * Indicates that the task has not been executed yet. 
  120.          */  
  121.         PENDING,  
  122.         /** 
  123.          * Indicates that the task is running. 
  124.          */  
  125.         RUNNING,  
  126.         /** 
  127.          * Indicates that {@link UserTask#onTaskFinished} has finished. 
  128.          */  
  129.         FINISHED,  
  130.     }  
  131.   
  132.     /** 
  133.      * UserTask的构造函数. 
  134.      * 
  135.      */  
  136.     public UserTask() {  
  137.         mWorker = new WorkerRunnable() {  
  138.             public Result call() throws Exception {  
  139.                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);  
  140.                 return onBackgroundExecute(mParams);  
  141.             }  
  142.         };  
  143.   
  144.         mFuture = new FutureTask(mWorker) {  
  145.             @Override  
  146.             protected void done() {  
  147.                 Message message;  
  148.                 Result result = null;  
  149.   
  150.                 try {  
  151.                     result = get();  
  152.                 } catch (InterruptedException e) {  
  153.                 } catch (ExecutionException e) {  
  154.                     throw new RuntimeException("An error occured while executing doInBackground()",  
  155.                             e.getCause());  
  156.                 } catch (CancellationException e) {  
  157.                     message = mHandler.obtainMessage(MESSAGE_POST_CANCEL,  
  158.                             new UserTaskResult(UserTask.this, (Result[]) null));  
  159.                     message.sendToTarget();  
  160.                     return;  
  161.                 } catch (Throwable t) {  
  162.                     throw new RuntimeException("An error occured while executing "  
  163.                             + "doInBackground()", t);  
  164.                 }  
  165.   
  166.                 //if(result == null) return; //赵小刚:If the result is null, return.  
  167.                 message = mHandler.obtainMessage(MESSAGE_POST_RESULT,  
  168.                         new UserTaskResult(UserTask.this, result));  
  169.                 message.sendToTarget();  
  170.             }  
  171.         };  
  172.     }  
  173.       
  174.     /** 
  175.      * UserTask的构造函数. 
  176.      * 
  177.      */  
  178.     public UserTask(Context context) {  
  179.         mContext = context;  
  180.         mWorker = new WorkerRunnable() {  
  181.             public Result call() throws Exception {  
  182.                 Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);  
  183.                 return onBackgroundExecute(mParams);  
  184.             }  
  185.         };  
  186.   
  187.         mFuture = new FutureTask(mWorker) {  
  188.             @Override  
  189.             protected void done() {  
  190.                 Message message;  
  191.                 Result result = null;  
  192.   
  193.                 try {  
  194.                     result = get();  
  195.                 } catch (InterruptedException e) {  
  196.                 } catch (ExecutionException e) {  
  197.                     throw new RuntimeException("An error occured while executing doInBackground()",  
  198.                             e.getCause());  
  199.                 } catch (CancellationException e) {  
  200.                     message = mHandler.obtainMessage(MESSAGE_POST_CANCEL,  
  201.                             new UserTaskResult(UserTask.this, (Result[]) null));  
  202.                     message.sendToTarget();  
  203.                     return;  
  204.                 } catch (Throwable t) {  
  205.                     throw new RuntimeException("An error occured while executing "  
  206.                             + "doInBackground()", t);  
  207.                 }  
  208.   
  209.                 //if(result == null) return; //赵小刚:If the result is null, return.  
  210.                 message = mHandler.obtainMessage(MESSAGE_POST_RESULT,  
  211.                         new UserTaskResult(UserTask.this, result));  
  212.                 message.sendToTarget();  
  213.             }  
  214.         };  
  215.     }  
  216.   
  217.     /** 
  218.      *返回当前任务的状态. 
  219.      * 
  220.      * @return The current status. 
  221.      */  
  222.     public final Status getStatus() {  
  223.         return mStatus;  
  224.     }  
  225.   
  226.     /** 
  227.      * 注册任务回调方法. 
  228.      * 
  229.      * @param callback the callback 
  230.      */  
  231.     public void registerCallback(TaskCallback callback) {  
  232.         this.mCallback = callback;  
  233.     }  
  234.       
  235.     /** 
  236.      * Override this method to perform a computation on a background thread. The 
  237.      * specified parameters are the parameters passed to {@link #execute} 
  238.      * by the caller of this task. 
  239.      * 
  240.      * This method can call {@link #publishProgress} to publish updates 
  241.      * on the thread. 
  242.      * 
  243.      * @param params The parameters of the task. 
  244.      * 
  245.      * @return A result, defined by the subclass of this task. 
  246.      * 
  247.      * @see #onPreExecute() 
  248.      * @see #onPostExecute 
  249.      * @see #publishProgress 
  250.      */  
  251.     protected  Result onBackgroundExecute(Params... params) {  
  252.         Result result = null;  
  253.         try {  
  254.             result = onCallbackExecute(params);  
  255.         } catch (Exception e) {  
  256.             this.mError = e;  
  257.         }  
  258.         return result;  
  259.     }  
  260.   
  261.     /** 
  262.      * Override to perform computation in a background thread. 
  263.      * 
  264.      * @param params the params 
  265.      * @return the result 
  266.      * @throws Exception the exception 
  267.      */  
  268.     protected Result onCallbackExecute(Params... params) throws Exception {  
  269.         return mCallback.call(UserTask.this, params);  
  270.     }  
  271.       
  272.     /** 
  273.      * Runs in the thread if there was an exception throw from onCallbackExecute. 
  274.      * 
  275.      * @param error The thrown exception. 
  276.      */  
  277.     protected abstract void onErrorHandle(Context context, Exception error);  
  278.       
  279.     /** 
  280.      * A replacement for onPostExecute. Runs in the thread after onCallbackExecute returns. 
  281.      * 
  282.      * @param result The result returned from onCallbackExecute 
  283.      */  
  284.     protected abstract void onTaskFinished(Context context, Result result);  
  285.       
  286.     /** 
  287.      * 在 {@link #onBackgroundExecute}之前执行. 
  288.      * 
  289.      * @see #onTaskPrepare 
  290.      * @see #onBackgroundExecute 
  291.      */  
  292.     protected void onTaskPrepare() {  
  293.     }  
  294.   
  295.     /** 
  296.      * 本方法在{@link #onBackgroundExecute}之后执行. The 
  297.      * specified result is the value returned by {@link #onBackgroundExecute} 
  298.      * or null if the task was cancelled or an exception occured. 
  299.      * 
  300.      * @param result The result of the operation computed by {@link #onBackgroundExecute}. 
  301.      * 
  302.      * @see #onPreExecute 
  303.      * @see #onBackgroundExecute 
  304.      */  
  305.     @SuppressWarnings({"UnusedDeclaration"})  
  306.     protected void onPostExecute(Result result) {  
  307.         if (onTaskFailed()) {  
  308.             onErrorHandle(mContext, mError);  
  309.         } else {  
  310.             onTaskFinished(mContext, result);  
  311.         }  
  312.     }  
  313.   
  314.     /** 
  315.      * 本方法的执行需要在在{@link #publishProgress}被调用之后. 
  316.      * The specified values are the values passed to {@link #publishProgress}. 
  317.      * 
  318.      * @param values The values indicating progress. 
  319.      * 
  320.      * @see #publishProgress 
  321.      * @see #onBackgroundExecute 
  322.      */  
  323.     @SuppressWarnings({"UnusedDeclaration"})  
  324.     protected void onProgressUpdate(Progress... values) {  
  325.     }  
  326.       
  327.     /** 
  328.      * Has an exception been thrown inside doCheckedInBackground(). 
  329.      * 
  330.      * @return true, if successful 
  331.      */  
  332.     protected boolean onTaskFailed() {  
  333.         return mError != null;  
  334.     }  
  335.   
  336.     /** 
  337.      * 在{@link #cancel(boolean)}被执行之后才能执行本方法. 
  338.      * 
  339.      * @see #cancel(boolean) 
  340.      * @see #isCancelled() 
  341.      */  
  342.     protected void onCancelled() {  
  343.     }  
  344.   
  345.     /** 
  346.      * Returns true if this task was cancelled before it completed 
  347.      * normally. 
  348.      * 
  349.      * @return true if task was cancelled before it completed 
  350.      * 
  351.      * @see #cancel(boolean) 
  352.      */  
  353.     public final boolean isCancelled() {  
  354.         return mFuture.isCancelled();  
  355.     }  
  356.   
  357.     /** 
  358.      * Attempts to cancel execution of this task.  This attempt will 
  359.      * fail if the task has already completed, already been cancelled, 
  360.      * or could not be cancelled for some other reason. If successful, 
  361.      * and this task has not started when cancel is called, 
  362.      * this task should never run.  If the task has already started, 
  363.      * then the mayInterruptIfRunning parameter determines 
  364.      * whether the thread executing this task should be interrupted in 
  365.      * an attempt to stop the task. 
  366.      * 
  367.      * @param mayInterruptIfRunning true if the thread executing this 
  368.      *        task should be interrupted; otherwise, in-progress tasks are allowed 
  369.      *        to complete. 
  370.      * 
  371.      * @return false if the task could not be cancelled, 
  372.      *         typically because it has already completed normally; 
  373.      *         true otherwise 
  374.      * 
  375.      * @see #isCancelled() 
  376.      * @see #onCancelled() 
  377.      */  
  378.     public final boolean cancel(boolean mayInterruptIfRunning) {  
  379.         return mFuture.cancel(mayInterruptIfRunning);  
  380.     }  
  381.   
  382.     /** 
  383.      * Waits if necessary for the computation to complete, and then 
  384.      * retrieves its result. 
  385.      * 
  386.      * @return The computed result. 
  387.      * @throws InterruptedException If the current thread was interrupted 
  388.      * while waiting. 
  389.      * @throws ExecutionException If the computation threw an exception. 
  390.      */  
  391.     public final Result get() throws InterruptedException, ExecutionException {  
  392.         return mFuture.get();  
  393.     }  
  394.   
  395.     /** 
  396.      * Waits if necessary for at most the given time for the computation 
  397.      * to complete, and then retrieves its result. 
  398.      * 
  399.      * @param timeout Time to wait before cancelling the operation. 
  400.      * @param unit The time unit for the timeout. 
  401.      * @return The computed result. 
  402.      * @throws InterruptedException If the current thread was interrupted 
  403.      * while waiting. 
  404.      * @throws ExecutionException If the computation threw an exception. 
  405.      * @throws TimeoutException If the wait timed out. 
  406.      */  
  407.     public final Result get(long timeout, TimeUnit unit) throws InterruptedException,  
  408.             ExecutionException, TimeoutException {  
  409.         return mFuture.get(timeout, unit);  
  410.     }  
  411.   
  412.     /** 
  413.      * execute方法返回自己(this),因此调用者可以保存它的引用 
  414.      *  
  415.      * 该方法可以在任何一个地方执行 
  416.      * 
  417.      * @param params The parameters of the task. 
  418.      * @return This instance of UserTask. 
  419.      * {@link UserTask.Status#RUNNING} or {@link UserTask.Status#FINISHED}. 
  420.      */  
  421.     public final UserTask execute(Params... params) {  
  422.         if (mStatus != Status.PENDING) {  
  423.             switch (mStatus) {  
  424.                 case RUNNING:  
  425.                     throw new IllegalStateException("Cannot execute task:"  
  426.                             + " the task is already running.");  
  427.                 case FINISHED:  
  428.                     throw new IllegalStateException("Cannot execute task:"  
  429.                             + " the task has already been executed "  
  430.                             + "(a task can be executed only once)");  
  431.             }  
  432.         }  
  433.   
  434.         mStatus = Status.RUNNING;  
  435.   
  436.         onTaskPrepare();  
  437.   
  438.         mWorker.mParams = params;  
  439.         mExecutor.execute(mFuture);  
  440.   
  441.         return this;  
  442.     }  
  443.   
  444.     /** 
  445.      * This method can be invoked from {@link #onBackgroundExecute} to 
  446.      * publish updates on the thread while the background computation is 
  447.      * still running. Each call to this method will trigger the execution of 
  448.      * 
  449.      * @param values The progress values to update the result. 
  450.      * {@link #onProgressUpdate} 
  451.      * @see #onProgressUpdate 
  452.      * @see #onBackgroundExecute 
  453.      */  
  454.     public final void publishProgress(Progress... values) {  
  455.         mHandler.obtainMessage(MESSAGE_POST_PROGRESS,  
  456.                 new UserTaskResult(this, values)).sendToTarget();  
  457.     }  
  458.   
  459.     /** 
  460.      * Finish. 
  461.      * 
  462.      * @param result the result 
  463.      */  
  464.     private void finish(Result result) {  
  465.         if (isCancelled()) result = null;  
  466.         onPostExecute(result);  
  467.         mStatus = Status.FINISHED;  
  468.     }  
  469.   
  470.     /** 
  471.      * The Class InternalHandler. 
  472.      */  
  473.     private static class InternalHandler extends Handler {  
  474.           
  475.         /* (non-Javadoc) 
  476.          * @see android.os.Handler#handleMessage(android.os.Message) 
  477.          */  
  478.         @SuppressWarnings({"unchecked""RawUseOfParameterizedType"})  
  479.         public void handleMessage(Message msg) {  
  480.             UserTaskResult result = (UserTaskResult) msg.obj;  
  481.             switch (msg.what) {  
  482.                 case MESSAGE_POST_RESULT:  
  483.                     // There is only one result  
  484.                     result.mTask.finish(result.mData[0]);  
  485.                     break;  
  486.                 case MESSAGE_POST_PROGRESS:  
  487.                     result.mTask.onProgressUpdate(result.mData);  
  488.                     break;  
  489.                 case MESSAGE_POST_CANCEL:  
  490.                     result.mTask.onCancelled();  
  491.                     break;  
  492.             }  
  493.         }  
  494.     }  
  495.   
  496.     /** 
  497.      * The Class WorkerRunnable. 
  498.      * 
  499.      * @param  the generic type 
  500.      * @param  the generic type 
  501.      */  
  502.      private static abstract class WorkerRunnable implements Callable {  
  503.           
  504.         /** The m params. */  
  505.         Params[] mParams;  
  506.     }  
  507.   
  508.     /** 
  509.      * The Class UserTaskResult. 
  510.      * 
  511.      * @param  the generic type 
  512.      */  
  513.     @SuppressWarnings({"RawUseOfParameterizedType""unchecked"})  
  514.     private static class UserTaskResult {  
  515.           
  516.         /** The m task. */  
  517.         final UserTask mTask;  
  518.           
  519.         /** The m data. */  
  520.         final Data[] mData;  
  521.           
  522.         /** 
  523.          * UserTaskResult的构造函数 
  524.          * 
  525.          * @param task the task 
  526.          * @param data the data 
  527.          */  
  528.         UserTaskResult(UserTask task, Data... data) {  
  529.             mTask = task;  
  530.             mData = data;  
  531.         }  
  532.     }  
  533.       
  534.     /** 
  535.      * TaskCallback接口用于实现UserTask的registerCallback方法. 
  536.      * 
  537.      * @param  the generic type 
  538.      * @param  the generic type 
  539.      * @param  the generic type 
  540.      */  
  541.     public interface TaskCallback {  
  542.           
  543.         /** 
  544.          * 耗时操作都放在在call方法里面 
  545.          * 
  546.          * @param task the task 
  547.          * @return the result 
  548.          * @throws AppException the app exception 
  549.          */  
  550.         public Result call(UserTask task, Params[] params) throws Exception;  
  551.     }  
  552. }  

下面是一个使用该类的实例:
view plain
  1. public class MainActivity extends Activity {  
  2.     /** Called when the activity is first created. */  
  3.     @Override  

你可能感兴趣的:(AsyncTask生命周期)