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类型即可。
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 实现异步加载图片
*/
public class MainActivity extends Activity {
public static final String IMG_URL="http://images.51cto.com/images/index/Images/Logo.gif";
Button btn_asynctask;
ImageView imgView;
ProgressBar progressBar;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//加载控件
imgView = (ImageView) this.findViewById(R.id.imageView);
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<String, Integer, Bitmap> {
/**在 doInParams...)之前被调用,在ui线程执行 **/
@Override
protected void onPreExecute() {
imgView.setImageBitmap(null);
progressBar.setProgress(); //进度条复位
}
/**在后台线程中执行的任务**/
protected Bitmap doInString... params) {
publishProgress(); //会调用onProgressUpdate更新界面
InputStream inputStream = null;
Bitmap imgBitmap = null;
try {
URL url = new URL(IMG_URL);
if(url != null) {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout();
connection.setDoInput(true);
connection.setRequestMethod("GET");
int code = connection.getResponseCode();
if( == code) {
inputStream = connection.getInputStream();
imgBitmap = BitmapFactory.decodeStream(inputStream);
}
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
publishProgress(); //下载完成,更新进度条为满格
//这里不是UI线程,故不能直接setImage(imgBitmap),
return imgBitmap;
}
/**在调用publishProgress之后被调用,在ui线程执行 **/
@Override
protected void onProgressUpdate(Integer... values) {
progressBar.setProgress(values[]); //设置进度条的进度
}
/**在后台线程执行完成之后,调用该方法,获取数据更新界面**/
@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线程执行 **/
protected void onCancelled() {
progressBar.setProgress();//进度条复位
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()中返回的对象。
Android 异步加载数据 AsyncTask异步更新界面的更多相关文章
- [Android Pro] 使用CursorLoader异步加载数据 from 3.0
Android 3.0引入了CursorLoader实现异步加载数据,为了避免同步查询数据库时阻塞UI线程的问题.在API 11之前可以通过下载支持库,来使之前的系统支持此功能,下载页面为 http: ...
- android 网络异步加载数据进度条
ProgressDialog progressDialog = null; public static final int MESSAGETYPE = 0; private void execute( ...
- winform异步加载数据到界面
做一个学习记录. 有两个需求: 1.点击按钮,异步加载数据,不卡顿UI. 2.把获取的数据加载到gridview上面. 对于需求1,2,代码如下: public delegate void ShowD ...
- 向上滚动或者向下滚动分页异步加载数据(Ajax + lazyload)[上拉加载组件]
/**** desc : 分页异步获取列表数据,页面向上滚动时候加载前面页码,向下滚动时加载后面页码 ajaxdata_url ajax异步的URL 如data.php page_val_name a ...
- 淘宝购物车页面 智能搜索框Ajax异步加载数据
如果有朋友对本篇文章的一些知识点不了解的话,可以先阅读此篇文章.在这篇文章中,我大概介绍了一下构建淘宝购物车页面需要的基础知识. 这篇文章主要探讨的是智能搜索框Ajax异步加载数据.jQuery的社区 ...
- Jquery zTree结合Asp.net实现异步加载数据
zTree结合Asp.net实现异步加载数据 实现简单操作 zTree 下载 api 访问 :http://www.ztree.me/v3/main.php 例子中用到json数据转化 newtons ...
- jquery easyui easyui-treegrid 使用异步加载数据
jquery easyui easyui-treegrid 使用异步加载数据 jquery easyui easyui-treegrid 异步请求 >>>>>>&g ...
- Highcharts 异步加载数据曲线图表
导入 data.js 文件 异步加载数据需要引入以下js 文件: <script src="http://code.highcharts.com/modules/data.js&quo ...
- [Ext.Net]TreePanel 异步加载数据
异步加载数据指的是页面加载的时候只显示根目录,点击根目录再去加载其子目录. 下面就来介绍下这种异步加载的树结构要怎么实现 现将例子的图 QQ图片20131225134353.jpg (12.1 KB, ...
随机推荐
- C# 简单的定时关机
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- LeetCode OJ 15. 3Sum
题目 Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all ...
- Oracle存储过程中使用临时表
一.Oracle临时表知识 在Oracle中,临时表分为SESSION.TRANSACTION两种,SESSION级的临时表数据在整个SESSION都存在,直到结束此次SESSION:而 TRANSA ...
- 第五次Scrum冲刺
第五次Scrum冲刺 1.成员今日完成情况 队员 今日完成任务 刘佳 前端初步构建 李佳 后端设计初级阶段 周世元 数据设计 杨小妮 博客编写 许燕婷 管理团队当日及次日任务 陈水莲 测试矩阵用例设计 ...
- centos6.5下oracle自动备份删除指定天数的文件
第一步先做一个备份 #!/bin/sh export ORACLE_BASE=/home/oracle/app export ORACLE_HOME=/dbhome_1 export ORACLE_S ...
- hibernate 工作原理及为什么要用
- idea gradle卡主问题
http://services.gradle.org/distributions/ 首先下载 all 版本 ,解压 ,再d盘, 并保留zip 文件 ,新建环境变量 GRADLE_HOME 指向 ...
- redis 存储java对象 两种方式
根据redis的存储原理,Redis的key和value都支持二进制安全的字符串 1.利用序列化和反序列化的方式存储java对象我们可以通过对象的序列化与反序列化完成存储于取出,这样就可以使用redi ...
- SQL Server - 使用 Merge 语句实现表数据之间的对比同步
表数据之间的同步有很多种实现方式,比如删除然后重新 INSERT,或者写一些其它的分支条件判断再加以 INSERT 或者 UPDATE 等.包括在 SSIS Package 中也可以通过 Lookup ...
- 使用SpirngMvc拦截器实现对登陆用户的身份验证
登陆成功则按returnUrl进行跳转,即跳转到登陆之前的页面,否则跳转到登陆页面,返回登陆错误信息. 1.SpringMVC.xml <!-- 映射器 --> <bean clas ...