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

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi