AsyncTask(异步任务)
一、AsyncTask
①AsyncTask的源码:
public abstract class AsyncTask<Params, Progress, Result>
三种泛型类型分别代表“启动任务执行的输入参数”、“后台任务执行的进度”、“后台计算结果的类型”。
②相关的方法:
一个异步任务的执行一般包括以下几个步骤:
1.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。
2.onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
3.doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。
4.onProgressUpdate(Progress... values),在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。
5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。
在使用的时候,有几点需要格外注意:
1.异步任务的实例必须在UI线程中创建。
2.execute(Params... params)方法必须在UI线程中调用。
3.不要手动调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法。
4.不能在doInBackground(Params... params)中更改UI组件的信息。
5.一个任务实例只能执行一次,如果执行第二次将会抛出异常。
(注:找资料的时候,看到挺详细的挺不错。 以上面内容转自:http://blog.csdn.NET/liuhe688/article/details/6532519)
二、案例
1、首先我们创建一个名为multithreadcho1的项目:
实现功能:
点击一个按钮,每隔3秒跟新一行item数据,进度条也显示,更新玩数据后改变TextView控件的值。
activity_main.xml布局文件:
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" /> <Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_marginLeft="72dp"
android:layout_toRightOf="@+id/textView1"
android:text="test" />
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/button1"
android:layout_marginTop="84dp" >
</ListView> <ProgressBar
android:id="@+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/listView1"
android:layout_alignRight="@+id/button1"
android:layout_below="@+id/button1"
android:layout_marginTop="28dp" />
图片:
item.xml布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" > <TextView
android:id="@+id/username"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="25dp"
android:textSize="25dp"
/> <TextView
android:id="@+id/sex"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="25dp"
android:textSize="25dp"
/>
</LinearLayout>
图片:
这两个TextView用来显示姓名和性别。
首先创建一个Userinfos类用来封装表的,添加两个字段 Name 和Sex。
Userinfos.java文件:
MainActivity.java文件:
public class MainActivity extends Activity {
private SimpleAdapter sa;
private Button btn;
private TextView tv;
private List<Userinfos> list=new ArrayList<Userinfos>();
private BaseAdapter adapter;
private ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
//这里是UI主线程
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); for (int i = 0; i < 5; i++) {
Userinfos u = new Userinfos();
u.setName("小明"+i);
u.setSex("男"+i);
list.add(u);
}
lv=(ListView)this.findViewById(R.id.listView1);
tv=(TextView)findViewById(R.id.textView1);
btn=(Button)findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener(){ //模拟数据访问产生数据
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Take tk=new Take(MainActivity.this);
tk.execute(list,adapter);//参数是传给doInBackground
}});
adapter=new BaseAdapter(){ @Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
} @Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
} @Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = MainActivity.this.getLayoutInflater();
View vw; if(convertView==null)
{
Log.i("View","创建对象");
vw = inflater.inflate(R.layout.item, null); }
else
{
vw=convertView;
}
TextView tv_username = (TextView)vw.findViewById(R.id.username);
TextView tv_sex = (TextView)vw.findViewById(R.id.sex);
tv_username.setText(list.get(position).getName());
tv_sex.setText(list.get(position).getSex());
return vw; }}; lv.setAdapter(adapter);
}
创建一个Take类继承AsyncTask,进行异步任务操作。
Take.java文件:
public class Take extends AsyncTask{
private MainActivity activity;
private BaseAdapter adapter;
private List<Userinfos> list=new ArrayList<Userinfos>();
protected Take(MainActivity activity)
{
this.activity=activity;
}
//后台运行(数据库,蓝牙,互联网)
@Override
protected Object doInBackground(Object... params) {
// TODO Auto-generated method stub
list = (List<Userinfos>) params[0];
Log.i("list",""+list.size());
adapter = (BaseAdapter) params[1]; for(int i=0;i<list.size();i++)
{
publishProgress(i); //这里的参数类型是 AsyncTask<Void, Integer, Void>中的Integer决定的,
//在onProgressUpdate中可以得到这个值去更新UI主线程,这里是异步线程 。
Log.i("time","休眠");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
list.get(i).setName("小红"+i);
list.get(i).setSex("女"+i); } return "天气:22度";
}
//准备
@Override
protected void onPreExecute() {
Toast.makeText(activity, "今晚有约", Toast.LENGTH_SHORT).show();
super.onPreExecute();
}
//做完后执行
@Override
protected void onPostExecute(Object result) {
//result的值为doInBackground方法的返回值
String tr=result.toString();
TextView tv = (TextView)activity.findViewById(R.id.textView1);
tv.setText("访问完成!"+tr);
// TODO Auto-generated method stub
super.onPostExecute(result);
}
//分步完成
//onProgressUpdate更新进度条
@Override
protected void onProgressUpdate(Object... values) {
// TODO Auto-generated method stub
Log.i("dd","进入分步");
int bar= Integer.parseInt(values[0].toString());
bar=(bar+1)*20;
ProgressBar progressBar = (ProgressBar)activity.findViewById(R.id.progressBar1);
progressBar.setProgress(bar);
adapter.notifyDataSetChanged();
//这里是UI主线程
}
}
1、通过继承AsyncTask,进行相关异步任务操作
2、调用 publishProgress(i)方法进入onProgressUpdate进度条更新的方法,通过BaseAdapter的notifyDataSetChanged()方法通知更新数据。
3、数据更新完后进入onPostExecute方法,该方法的result参数的值为doInBackground方法的返回值,我们固定让它返回字符串。
4、将doInBackground方法返回的值赋给TextView。
效果图片:
AsyncTask(异步任务)的更多相关文章
- Android线程管理之AsyncTask异步任务
前言: 前面几篇文章主要学习了线程以及线程池的创建与使用,今天来学习一下AsyncTask异步任务,学习下AsyncTask到底解决了什么问题?然而它有什么弊端?正所谓知己知彼百战百胜嘛! 线程管理相 ...
- AsyncTask异步交互和httpurlconnection结合使用
//网络请求数据 package com.baidu.myutils; import java.io.BufferedReader; import java.io.InputStreamReader; ...
- Android多线程分析之五:使用AsyncTask异步下载图像
Android多线程分析之五:使用AsyncTask异步下载图像 罗朝辉 (http://www.cnblogs.com/kesalin) CC 许可,转载请注明出处 在本系列文章的第一篇<An ...
- 使用AsyncTask异步更新UI界面及原理分析
概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...
- Android 多线程----AsyncTask异步任务详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...
- android AsyncTask异步下载并更新进度条
AsyncTask异步下载并更新进度条 //如果不是很明白请看上篇文章的异步下载 AsyncTask<String, Integer, String> 第一个参数:String 传入 ...
- Android中使用Thread线程与AsyncTask异步任务的区别
最近和几个朋友交流Android开发中的网络下载问题时,谈到了用Thread开启下载线程时会产生的Bug,其实直接用子线程开启下载任务的确是很Low的做法,那么原因究竟如何,而比较高大上的做法是怎样? ...
- Android异步处理系列文章四篇之二 使用AsyncTask异步更新UI界面
Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...
- Android使用AsyncTask异步线程网络通信获取数据(get json)
摘要: android 4.0以上强制要求不能在主线程执行耗时的网络操作,网络操作需要使用Thead+Handler或AsyncTask,本文将介绍AsyncTask的使用方法. 内容: 1.添加Ht ...
- Android异步处理二:使用AsyncTask异步更新UI界面
在<Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面>中,我们使用Thread+Handler的方式实现了异步更新UI界面,这一篇中,我们介绍一种更为简 ...
随机推荐
- MQTT简介
MQTT简介 MQTT是IBM开发的一个即时通讯协议,该协议支持所有的平台,几乎可以把所有联网的物品和外部连接起来,被用来当做传感器和致动器(比如通过Twitter让房屋联网)的通信协议 MQTT的特 ...
- Wireshark 过滤器语法
wireshark有两种过滤器: 捕捉过滤器(CaptureFilters):用于决定将什么样的信息记录在捕捉结果中. 显示过滤器(DisplayFilters):用于在捕捉结果中进行详细查找. 捕捉 ...
- numpy delete
手动安装 sudo rm -rf /usr/local/lib/python2.7/site-packages/numpy/ sudo rm -rf /usr/local/lib/python2.7/ ...
- MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.3 Displaying Classes in a Layer
MapServer Tutorial——MapServer7.2.1教程学习——第一节用例实践:Example1.3 Displaying Classes in a Layer 一.前言 关于第一节的 ...
- react 表单获取多个input
react 表单this.handleChange(key,e){ [key]:e.target.value} submit=()=>{ const {userName,age,status} ...
- 安装Ruby、Sass在WebStrom配置Scss编译环境css自动压缩
安装Sass和Compass sass基于Ruby语言开发而成,因此安装sass前需要安装Ruby.(注:mac下自带Ruby无需在安装Ruby!) window下安装SASS首先需要安装Ruby,先 ...
- hadoop fsck详解
我们知道fsck是用来检测hdfs上文件.block信息的,但是fsck输出的结果我们是否能看明白呢? 下面我们来看一个fsck输出的结果 hadoop fsck / ############## ...
- 高级数据类型-- 字符串(str),切片
一.字符串 字符串 就是 一串字符,是编程语言中表示文本的数据类型 在 Python 中可以使用 一对双引号" 或者 一对单引号' 定义一个字符串 虽然可以使用 \" 或者 \' ...
- 学号 20175223 《Java程序设计》第4周学习总结
学号 20175223 <Java程序设计>第4周学习总结 教材学习内容总结 第五章要点: 要点1:子类与父类:extends.类的树形结构: 要点2:子类的继承性:同一包中与不在同一包中 ...
- java正则表达式appendReplacement和appendTail方法
appendReplacement是java中替换相应字符串的一个方法 appendReplacement(StringBuffer sb,String replacement) 将当前匹配子串替换为 ...