Android 异步加载数据 AsyncTask异步更新界面

官方文档:
    AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
    AsyncTask能够更恰当和更简单的去使用UI线程。这个类允许执行后台操作和展现结果在UI线程上,无需操纵线程和/或处理程序。AsyncTask的内部实现是一个线程池,每个后台任务会提交到线程池中的线程执行,然后使用Thread+Handler的方式调用回调函数。
   
1.AsyncTask抽象出后台线程运行的五个状态:
    分别是:1、准备运行,2、正在后台运行,3、进度更新,4、完成后台任务,5、取消任务,对于这五个阶段,AsyncTask提供了五个回调函数:

    1、准备运行:onPreExecute(),该回调函数在任务被执行之后立即由UI线程调用。这个步骤通常用来建立任务,在用户接口(UI)上显示进度条。
    2、正在后台运行:doInParams...),该回调函数由后台线程在onPreExecute()方法执行结束后立即调用。通常在这里执行耗时的后 台计算。计算的结果必须由该函数返回,并被传递到onPostExecute()中。在该函数内也可以使用 publishProgress(Progress...)来发布一个或多个进度单位(unitsof progress)。这些值将会在onProgressUpdate(Progress...)中被发布到UI线程。
    3. 进度更新:onProgressUpdate(Progress...),该函数由UI线程在publishProgress(Progress...)方法调用完后被调用。一般用于动态地显示一个进度条。
    4. 完成后台任务:onPostExecute(Result),当后台计算结束后调用。后台计算的结果会被作为参数传递给这一函数。
    5、取消任务:onCancelled (),在调用AsyncTask的cancel()方法时调用
2.使用:
    AsyncTask必须使用子类。子类会覆盖至少一个方法(doInParams…)),通常将覆盖第二个(onPostExecute(结果)。
AsyncTask的构造函数有三个模板参数:<Params, Progress, Result>

  1.Params,传递给后台任务的参数类型。
  2.Progress,后台计算执行过程中,进步单位(progress units)的类型。(就是后台程序已经执行了百分之几了。)
  3.Result, 后台执行返回的结果的类型。
  AsyncTask并不总是需要使用上面的全部3种类型。标识不使用的类型很简单,只需要使用Void类型即可。

  1     import java.io.InputStream;
  2 
  3     import java.net.HttpURLConnection;
  4 
  5     import java.net.URL;
  6 
  7     import android.app.Activity;
  8 
  9     import android.graphics.Bitmap;
 10 
 11     import android.graphics.BitmapFactory;
 12 
 13     import android.os.AsyncTask;
 14 
 15     import android.os.Bundle;
 16 
 17     import android.view.View;
 18 
 19     import android.view.View.OnClickListener;
 20 
 21     import android.widget.Button;
 22 
 23     import android.widget.ImageView;
 24 
 25     import android.widget.ProgressBar;
 26 
 27     import android.widget.Toast;
 28 
 29     /**
 30 
 31     * AsyncTask  实现异步加载图片
 32 
 33     */
 34     public class MainActivity extends Activity {
 35 
 36                                                                                                                                            
 37 
 38         public static  final String IMG_URL="http://images.51cto.com/images/index/Images/Logo.gif";
 39 
 40         Button btn_asynctask;
 41 
 42         ImageView imgView;
 43 
 44         ProgressBar progressBar;
 45 
 46         protected void onCreate(Bundle savedInstanceState) {
 47 
 48             super.onCreate(savedInstanceState);
 49 
 50             setContentView(R.layout.activity_main);
 51 
 52             //加载控件
 53 
 54             imgView = (ImageView) this.findViewById(R.id.imageView);
 55 
 56             btn_asynctask = (Button) this.findViewById(R.id.btn_AsyncTask);
 57 
 58             progressBar = (ProgressBar) this.findViewById(R.id.progressBar);
 59 
 60             //绑定监听器
 61 
 62             btn_asynctask.setOnClickListener(new OnClickListener() {
 63 
 64                 @Override
 65 
 66                 public void onClick(View v) {
 67 
 68                     GetImgTask getImgTask = new GetImgTask();
 69 
 70                     getImgTask.execute(IMG_URL); //执行该任务
 71 
 72                 }
 73 
 74             });
 75 
 76         }
 77 
 78                                                                                                                                            
 79 
 80         /**获取网络图片任务**/
 81 
 82         private class GetImgTask extends AsyncTask<String, Integer, Bitmap> {
 83 
 84                                                                                                                                                 
 85 
 86             /**在 doInParams...)之前被调用,在ui线程执行   **/
 87 
 88             @Override
 89 
 90             protected void onPreExecute() {
 91 
 92                  imgView.setImageBitmap(null);
 93 
 94                  progressBar.setProgress(0);    //进度条复位
 95 
 96             }
 97 
 98                                                                                                                                                 
 99 
100             /**在后台线程中执行的任务**/
101             protected Bitmap doInString...  params) {
102 
103                                                                                                                                                     
104 
105                 publishProgress(0); //会调用onProgressUpdate更新界面
106 
107                                                                                                                                                     
108                 InputStream inputStream = null;
109                 Bitmap imgBitmap = null;
110                 try {
111 
112                     URL url = new URL(IMG_URL);
113 
114                     if(url != null) {
115 
116                         HttpURLConnection connection = (HttpURLConnection) url.openConnection();
117 
118                         connection.setConnectTimeout(2000);
119 
120                         connection.setDoInput(true);
121 
122                         connection.setRequestMethod("GET");
123 
124                         int code = connection.getResponseCode();
125 
126                         if(200 == code) {
127 
128                             inputStream = connection.getInputStream();
129 
130                             imgBitmap = BitmapFactory.decodeStream(inputStream);
131 
132                         }
133 
134                     }
135 
136                 } catch (Exception e) {
137 
138                     e.printStackTrace();
139 
140                     return null;
141 
142                 }
143 
144                 publishProgress(100); //下载完成,更新进度条为满格
145 
146                 //这里不是UI线程,故不能直接setImage(imgBitmap),
147 
148                 return imgBitmap;
149 
150             }
151 
152                                                                                                                                                 
153 
154             /**在调用publishProgress之后被调用,在ui线程执行  **/
155 
156             @Override
157 
158             protected void onProgressUpdate(Integer... values) {
159 
160                 progressBar.setProgress(values[0]);  //设置进度条的进度
161 
162             }
163 
164             /**在后台线程执行完成之后,调用该方法,获取数据更新界面**/
165 
166             @Override
167 
168             protected void onPostExecute(Bitmap result) {
169 
170                 if(result != null) {
171 
172                     Toast.makeText(MainActivity.this, "成功获取图片", Toast.LENGTH_LONG).show();
173 
174                     imgView.setImageBitmap(result);
175 
176                 }else {
177 
178                     Toast.makeText(MainActivity.this, "获取图片失败", Toast.LENGTH_LONG).show();
179 
180                 }
181             }
182 
183             /**取消任务,在ui线程执行 **/
184             protected void onCancelled() {
185 
186                 progressBar.setProgress(0);//进度条复位
187 
188                 super.onCancelled();
189             }
190         }
191     }

分析:

    1.点击按钮之后,创建一个任务,参数值为url(所以第一个参数为String)

    2.UI线程执行onPreExecute(),把ImageView的图片清空,progrssbar的进度清零。
    3.后台线程执行doInBackground(),不可以在doInBackground()操作ui,调用publishProgress(0)更新 进度,此时会调用onProgressUpdate(Integer...progress)更新进度条(进度用整形表示,因此AsyncTask的第二 个模板参数是Integer)。函数最后返回result(例子中是返回Bitmap类型,因此AsyncTask的第三个模板参数是Bitmap)。
    4.当后台任务执行完成后,调用onPostExecute(Result),传入的参数是doInBackground()中返回的对象。

这世界上有一种鸟是没有脚的,它只能够一直的飞呀飞呀,飞累了就在风里面睡觉,这种鸟一辈子只能下地一次,那一次就是它死亡的时候。
原文地址:https://www.cnblogs.com/xuyinghui/p/4665179.html