Android中异步加载数据(二)AsyncTask异步更新界面

2024-06-08 20:48

本文主要是介绍Android中异步加载数据(二)AsyncTask异步更新界面,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android中异步加载数据(二)AsyncTask异步更新界面

作者: 狂奔的蜗牛 发布日期:2013-07-19 10:10:18
我来说两句(0)
Tag标签: Android 异步加载 AsyncTask 异步更新
  • 今天介绍第二种异步更新界面的方式: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<Params, Progress, Result>

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

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

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

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


    view source print ?
    001. import java.io.InputStream;
    002. import java.net.HttpURLConnection;
    003. import java.net.URL;
    004. import android.app.Activity;
    005. import android.graphics.Bitmap;
    006. import android.graphics.BitmapFactory;
    007. import android.os.AsyncTask;
    008. import android.os.Bundle;
    009. import android.view.View;
    010. import android.view.View.OnClickListener;
    011. import android.widget.Button;
    012. import android.widget.ImageView;
    013. import android.widget.ProgressBar;
    014. import android.widget.Toast;
    015. /**
    016. * AsyncTask 实现异步加载图片
    017. * @author ZHF
    018. *
    019. */
    020. public class MainActivity extends Activity {
    021.
    022. public static final String IMG_URL="http://images.51cto.com/images/index/Images/Logo.gif";
    023. Button btn_asynctask;
    024. ImageView imgView;
    025. ProgressBar progressBar;
    026.
    027. @Override
    028. protected void onCreate(Bundle savedInstanceState) {
    029. super.onCreate(savedInstanceState);
    030. setContentView(R.layout.activity_main);
    031. //加载控件
    032. imgView = (ImageView) this.findViewById(R.id.imageView);
    033. btn_asynctask = (Button) this.findViewById(R.id.btn_AsyncTask);
    034. progressBar = (ProgressBar) this.findViewById(R.id.progressBar);
    035. //绑定监听器
    036. btn_asynctask.setOnClickListener(new OnClickListener() {
    037. @Override
    038. public void onClick(View v) {
    039. GetImgTask getImgTask = new GetImgTask();
    040. getImgTask.execute(IMG_URL); //执行该任务
    041. }
    042. });
    043. }
    044.
    045. /**获取网络图片任务**/
    046. private class GetImgTask extends AsyncTask<String, Integer, Bitmap> {
    047.
    048. /**在 doInParams...)之前被调用,在ui线程执行 **/
    049. @Override
    050. protected void onPreExecute() {
    051. imgView.setImageBitmap(null);
    052. progressBar.setProgress(0); //进度条复位
    053. }
    054.
    055. /**在后台线程中执行的任务**/
    056. @Override
    057. protected Bitmap doInString... params) {
    058.
    059. publishProgress(0); //会调用onProgressUpdate更新界面
    060.
    061. InputStream inputStream = null;
    062. Bitmap imgBitmap = null;
    063. try {
    064. URL url = new URL(IMG_URL);
    065. if(url != null) {
    066. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    067. connection.setConnectTimeout(2000);
    068. connection.setDoInput(true);
    069. connection.setRequestMethod("GET");
    070. int code = connection.getResponseCode();
    071. if(200 == code) {
    072. inputStream = connection.getInputStream();
    073. imgBitmap = BitmapFactory.decodeStream(inputStream);
    074. }
    075. }
    076. } catch (Exception e) {
    077. e.printStackTrace();
    078. return null;
    079. }
    080. publishProgress(100); //下载完成,更新进度条为满格
    081. //这里不是UI线程,故不能直接setImage(imgBitmap),
    082. return imgBitmap;
    083. }
    084.
    085. /**在调用publishProgress之后被调用,在ui线程执行 **/
    086. @Override
    087. protected void onProgressUpdate(Integer... values) {
    088. progressBar.setProgress(values[0]); //设置进度条的进度
    089. }
    090. /**在后台线程执行完成之后,调用该方法,获取数据更新界面**/
    091. @Override
    092. protected void onPostExecute(Bitmap result) {
    093. if(result != null) {
    094. Toast.makeText(MainActivity.this, "成功获取图片", Toast.LENGTH_LONG).show();
    095. imgView.setImageBitmap(result);
    096. }else {
    097. Toast.makeText(MainActivity.this, "获取图片失败", Toast.LENGTH_LONG).show();
    098. }
    099. }
    100. /**取消任务,在ui线程执行 **/
    101. @Override
    102. protected void onCancelled() {
    103. progressBar.setProgress(0);//进度条复位
    104. super.onCancelled();
    105. }
    106. }
    107. }

    分析:

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

这篇关于Android中异步加载数据(二)AsyncTask异步更新界面的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1043267

相关文章

SpringBoot实现接口数据加解密的三种实战方案

《SpringBoot实现接口数据加解密的三种实战方案》在金融支付、用户隐私信息传输等场景中,接口数据若以明文传输,极易被中间人攻击窃取,SpringBoot提供了多种优雅的加解密实现方案,本文将从原... 目录一、为什么需要接口数据加解密?二、核心加解密算法选择1. 对称加密(AES)2. 非对称加密(R

详解如何在SpringBoot控制器中处理用户数据

《详解如何在SpringBoot控制器中处理用户数据》在SpringBoot应用开发中,控制器(Controller)扮演着至关重要的角色,它负责接收用户请求、处理数据并返回响应,本文将深入浅出地讲解... 目录一、获取请求参数1.1 获取查询参数1.2 获取路径参数二、处理表单提交2.1 处理表单数据三、

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Oracle 通过 ROWID 批量更新表的方法

《Oracle通过ROWID批量更新表的方法》在Oracle数据库中,使用ROWID进行批量更新是一种高效的更新方法,因为它直接定位到物理行位置,避免了通过索引查找的开销,下面给大家介绍Orac... 目录oracle 通过 ROWID 批量更新表ROWID 基本概念性能优化建议性能UoTrFPH优化建议注

在 PyQt 加载 UI 三种常见方法

《在PyQt加载UI三种常见方法》在PyQt中,加载UI文件通常指的是使用QtDesigner设计的.ui文件,并将其转换为Python代码,以便在PyQt应用程序中使用,这篇文章给大家介绍在... 目录方法一:使用 uic 模块动态加载 (不推荐用于大型项目)方法二:将 UI 文件编译为 python 模

Spring Validation中9个数据校验工具使用指南

《SpringValidation中9个数据校验工具使用指南》SpringValidation作为Spring生态系统的重要组成部分,提供了一套强大而灵活的数据校验机制,本文给大家介绍了Spring... 目录1. Bean Validation基础注解常用注解示例在控制器中应用2. 自定义约束验证器定义自

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

C#实现高性能Excel百万数据导出优化实战指南

《C#实现高性能Excel百万数据导出优化实战指南》在日常工作中,Excel数据导出是一个常见的需求,然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈,下面我们看看C#如何结合EPPl... 目录一、技术方案核心对比二、各方案选型建议三、性能对比数据四、核心代码实现1. MiniExcel

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

SQL常用操作精华之复制表、跨库查询、删除重复数据

《SQL常用操作精华之复制表、跨库查询、删除重复数据》:本文主要介绍SQL常用操作精华之复制表、跨库查询、删除重复数据,这些SQL操作涵盖了数据库开发中最常用的技术点,包括表操作、数据查询、数据管... 目录SQL常用操作精华总结表结构与数据操作高级查询技巧SQL常用操作精华总结表结构与数据操作复制表结