热门IT资讯网

【移动开发】Android中异步加载数据(二)AsyncTask异步更新界面

发表于:2024-11-24 作者:热门IT资讯网编辑
编辑最后更新 2024年11月24日,今天介绍第二种异步更新界面的方式:AsyncTask官方文档:AsyncTask enables proper and easy use of the UI thread. This class al

今天介绍第二种异步更新界面的方式: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(结果)。< /span>

AsyncTask的构造函数有三个模板参数:AsyncTask, Result>

1.Params,传递给后台任务的参数类型。

2.Progress,后台计算执行过程中,进步单位(progress units)的类型。(就是后台程序已经执行了百分之几了。)

3.Result, 后台执行返回的结果的类型。


AsyncTask并不总是需要使用上面的全部3种类型。标识不使用的类型很简单,只需要使用Void类型即可。

import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;import android.widget.ProgressBar;import android.widget.Toast;/** * AsyncTask  实现异步加载图片 * @author ZHF * */public class MainActivity extends Activity {                                                                                                                                           public static  final String IMG_URL="https://cache.yisu.com/upload/information/20200312/67/252447.jpg";    Button btn_asynctask;    ImageView imgView;    ProgressBar progressBar;                                                                                                                                           @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //加载控件        imgView = (ImageView) this.findViewById(R.id.p_w_picpathView);        btn_asynctask = (Button) this.findViewById(R.id.btn_AsyncTask);        progressBar = (ProgressBar) this.findViewById(R.id.progressBar);        //绑定监听器        btn_asynctask.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                GetImgTask getImgTask = new GetImgTask();                getImgTask.execute(IMG_URL); //执行该任务            }        });    }                                                                                                                                           /**获取网络图片任务**/    private class GetImgTask extends AsyncTask {                                                                                                                                                   /**在 doInParams...)之前被调用,在ui线程执行   **/        @Override        protected void onPreExecute() {             imgView.setImageBitmap(null);              progressBar.setProgress(0);    //进度条复位         }                                                                                                                                                   /**在后台线程中执行的任务**/        @Override        protected Bitmap doInString...  params) {                                                                                                                                                           publishProgress(0); //会调用onProgressUpdate更新界面                                                                                                                                                           InputStream inputStream = null;            Bitmap imgBitmap = null;            try {                URL url = new URL(IMG_URL);                if(url != null) {                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();                    connection.setConnectTimeout(2000);                    connection.setDoInput(true);                    connection.setRequestMethod("GET");                    int code = connection.getResponseCode();                    if(200 == code) {                        inputStream = connection.getInputStream();                        imgBitmap = BitmapFactory.decodeStream(inputStream);                    }                }            } catch (Exception e) {                e.printStackTrace();                return null;            }            publishProgress(100); //下载完成,更新进度条为满格            //这里不是UI线程,故不能直接setImage(imgBitmap),            return imgBitmap;        }                                                                                                                                                   /**在调用publishProgress之后被调用,在ui线程执行  **/        @Override        protected void onProgressUpdate(Integer... values) {            progressBar.setProgress(values[0]);  //设置进度条的进度        }        /**在后台线程执行完成之后,调用该方法,获取数据更新界面**/        @Override        protected void onPostExecute(Bitmap result) {            if(result != null) {                 Toast.makeText(MainActivity.this, "成功获取图片", Toast.LENGTH_LONG).show();                 imgView.setImageBitmap(result);             }else {                 Toast.makeText(MainActivity.this, "获取图片失败", Toast.LENGTH_LONG).show();             }         }        /**取消任务,在ui线程执行 **/        @Override        protected void onCancelled() {            progressBar.setProgress(0);//进度条复位             super.onCancelled();        }    }}

分析:

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()中返回的对象。


参考博客:http://blog.csdn.net/mylzc/article/details/6772129


×××请看附件


附件:http://down.51cto.com/data/2363166
0