Android_AsyncTask异步任务机制
今天我们学习了 AsyncTack, 这是一个异步任务。
那么这个异步任务可以干什么呢?
因为只有UI线程,即主线程可以对控件进行更新操作。好处是保证UI稳定性,避免多线程对UI同时操作。
同时要把耗时任务放在非主线程中执行,否则会造成阻塞,抛出无响应异常。
那么在Android中实现异步任务机制有两种方式,Handler和AsyncTask。今天主要讲的是 asyncTack.
我们通过API 来学习下 整个 AsyncTack
一、结构
继承关系
public abstract class AsyncTask extends Object
java.lang.Object
android.os.AsyncTask <params,Progress,Result>
二、类概述
AsyncTask 能够适当的,简单的用于 UI 线程。这个类不需要操作线程(Thread)就可以完成后台操作将结果返回 UI
异步任务的定义是一个在后台线程上运行,其结果是在UI线程上发布的计算。
异步任务被定义成
三种泛型类型:
Params:启动任务执行的输入参数。
Progress:后台人数执行的百分比
Result:后台计算的结果类型
注:在一个异步任务中,不是所有的类型总被用。假如一个类型不被使用,可以简单地使用void 类型。
四个步骤:
1.onPreExecute():在UI线程上调用任务后立即执行。这步通常被用于设置任务,例如在用户界面显示一个进度条。
2.doInBackground(Params...):后台线程执行 onPreExecute()完成立即调用,这步被用于执行较长时间的后台计算。异步任务的参数也被传到这步。计算的结果必须在这步返回,将返回到上一步。在执行过程中可以调用 publishProgress(Progress...)来更新人无语的进度。
3.onProcessProgress():一次呼叫 publishProgress(Progress...)后调用UI线程。执行时间是不确定的。这个方法用于当后台计算还在进行时在用户界面显示进度。例如:这个方法可以被用于一个进度条动画或在文本域显示记录。
4.onPostExecute(Resule):当后台计算结束时,调用 UI线程。后台计算结果作为一个参数传递到这步。
接下来我们用一个栗子看看这个 AsyncTask 到底能做什么。
这是我们的xml 布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.multithreadind01.MainActivity" > <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_alignParentRight="true"
android:layout_alignTop="@+id/textView1"
android:layout_marginRight="53dp"
android:text="Button" /> <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" /> </RelativeLayout>
这是我们listView xml 的布局文件
<?xml version="1.0" encoding="utf-8"?>
<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="60dp"
android:textSize="45dp"
/> <TextView
android:id="@+id/sex"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="60dp"
android:textSize="45dp"
/>
</LinearLayout>
这是我们的 user.class
package com.example.multithreadind01;
public class User {
private String username;
private String sex;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
MainActivity.class
package com.example.multithreadind01; import java.util.ArrayList;
import java.util.List; import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView; public class MainActivity extends Activity { private String fromDb_str1 = "";
private Button btn;
private TextView tv;
private ListView lv;
private BaseAdapter adapter;
private List<User> userList = new ArrayList<User>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //模拟数据访问产生数据
for (int i = 0; i < 5; i++) {
User u = new User();
u.setUsername("小明"+i);
u.setSex("女"+i);
userList.add(u);
} tv =(TextView)findViewById(R.id.textView1);
btn =(Button)findViewById(R.id.button1);
btn.setOnClickListener(new OnClickListener() { @Override
public void onClick(View v) {
MyTask mt = new MyTask(MainActivity.this);
mt.execute(userList,adapter);//里面的参数是传给doInBackground
/*
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
fromDb_str1 = "测试";
}
});
t1.start();
tv.setText(fromDb_str1);
*/ }
});
adapter = new BaseAdapter(){ @Override
public int getCount() {
// TODO Auto-generated method stub
return userList.size();
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = MainActivity.this.getLayoutInflater();
View view;
if (convertView==null){
view = inflater.inflate(R.layout.item, null);
}
else{
view = convertView;
} TextView tv_username = (TextView)view.findViewById(R.id.username);
TextView tv_sex = (TextView)view.findViewById(R.id.sex);
tv_username.setText(userList.get(position).getUsername());
tv_sex.setText(userList.get(position).getSex());
return view;
} @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;
}
};
lv = (ListView)findViewById(R.id.listView1);
lv.setAdapter(adapter);
}
}
最后是我们异步类 MyTask.class
package com.example.multithreadind01; import java.util.List; import android.os.AsyncTask;
import android.view.View;
import android.widget.BaseAdapter;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast; public class MyTask extends AsyncTask { private BaseAdapter adapter;
private List<User> userList;
private MainActivity activity;
public MyTask(MainActivity activity){
this.activity = activity;
} //1.所有耗时的代码,写到这里来(数据库、蓝牙、网络服务)
//2.绝对不能碰UI
@Override
protected Object doInBackground(Object... params) { userList = (List<User>) params[0];
adapter = (BaseAdapter) params[1];
for (int i = 0; i < userList.size(); i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
userList.get(i).setUsername("小红"+i);
userList.get(i).setSex("男"+i);
publishProgress(i);
} //userlist,adapter //返回给前端
return "天气:22度";
} //准备
@Override
protected void onPreExecute() {
Toast.makeText(activity, "hello ,今晚约不约", Toast.LENGTH_SHORT).show(); } //做完后执行
@Override
protected void onPostExecute(Object result) {
String r = result.toString();
TextView tv = (TextView)activity.findViewById(R.id.textView1);
tv.setText("访问完成!"+r); } //分步完成
@Override
protected void onProgressUpdate(Object... values) { //0,1,2,3,4
int bar = Integer.parseInt(values[0].toString());
bar = (bar+1)*20;
ProgressBar progressBar = (ProgressBar)activity.findViewById(R.id.progressBar1);
progressBar.setProgress(bar);
adapter.notifyDataSetChanged();
} }
以上案例使我们做到后台数据加载到前端的过程中,使用异步,不会出现所谓的“卡顿”。使得整个程序运行的效果是畅通的,用户体验性也提高。



Android_AsyncTask异步任务机制的更多相关文章
- Android异步任务机制之AsycTask
在Android中实现异步任务机制有两种方式,Handler和AsyncTask. 本篇就说说AsyncTask的异步实现. 1.什么时候使用 AsnyncTask 在上一篇文章已经说了,主线程主要负 ...
- Android异步消息处理机制
安卓子线程无法直接更改UI,所以需要异步消息处理机制来解决 <?xml version="1.0" encoding="utf-8"?><Li ...
- Android 异步消息处理机制解析
Android 中的异步消息处理主要由四个部分组成,Message.Handler.MessageQueue.Looper.下面将会对这四个部分进行一下简要的介绍. 1. Message: Messa ...
- Android多线程----异步消息处理机制之Handler详解
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...
- 【译】深入理解python3.4中Asyncio库与Node.js的异步IO机制
转载自http://xidui.github.io/2015/10/29/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3python3-4-Asyncio%E5%BA%93% ...
- 【转】Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 很多人面试肯定都被问到过,请问Andr ...
- Android开发之异步消息处理机制AsyncTask
转自:Android AsyncTask完全解析,带你从源码的角度彻底理解 另外一篇比较详细的博文:http://blog.csdn.net/liuhe688/article/details/6532 ...
- Android线程与异步消息处理机制
在程序开发时,对于一些比较耗时的操作,我们通常会为其开辟一个单独的线程来执行,这样可以尽可能的减少用户等待的时间.在Android中,默认情况下,所有的操作都是在主线程中进行的,这个主线程负责管理与U ...
- Android Learning:多线程与异步消息处理机制
在最近学习Android项目源码的过程中,遇到了很多多线程以及异步消息处理的机制.由于之前对这块的知识只是浅尝辄止,并没有系统的理解.但是工程中反复出现让我意识到这个知识的重要性.所以我整理出这篇博客 ...
随机推荐
- [转]-CSS 元素垂直居中的6种方法
原文地址:http://blog.zhourunsheng.com/2012/03/css-%E5%85%83%E7%B4%A0%E5%9E%82%E7%9B%B4%E5%B1%85%E4%B8%AD ...
- A New Beginning
不知不觉中,接触前端已经快两个月了,从一开始的懵懂无知,到现在的--依旧不是很懂,似乎浪费了很多时间,一直都有记纸质笔记.写总结的习惯,写满一本又换一本,却在不知不觉中忽略了自己的实践能力,花费了太多 ...
- 那些年蹚过的坑(c++)
1 main中的参数 尽量用英文双引号括起来,否则可能会出现字符串截断的情况(linux gcc 4.4 不加英文引号的话,遇到英文;会丢弃;后面的部分) 2 包含ipv6地址结构体(in6_addr ...
- Laravel excel安装与使用
在 Laravel 5 中使用 Laravel Excel 实现 Excel/CSV 文件导入导出功能 时间 2015-11-17 18:40:56 Laravel学院 原文 http://lar ...
- ssh 服务器之间公钥认证方式的配置
前言 项目中需要编写脚本在服务器之间上传或者下载文件,但没有相关服务器来测试脚本,于是就着手安装两台server,然后用ssh的相关命令去配置server之间公钥认证登录. 步骤 1. 在VM Box ...
- js疑问
var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];var aCopy = arr.slice();aCopy; // ['A', 'B', 'C', 'D', ...
- delphi.指针.PChar
此文是delphi.指针.应用姊妹篇,想细化一下PChar应用,所以有了此文. 注意: 1:此文讲的是PChar与字符串相关操作,其它方法暂不多讲. 2:由于D分开Ansi/Unicode的两种完全不 ...
- js判断是否是移动设备登陆网页
var browser = { versions: function () { var u = navigator.userAgent, app = ...
- Salesforce 使用Js 调用Webservice实例
1,创建 Custom Button 在页面上 2, 创建CustomJs 代码调用Webservice <!--参数名区分大小写,对于跨层object直接在Object名后直接加参字段名即可- ...
- Geometry shader总结
什么是Geometry Shader GS存在于vertext shader和固定功能vertex post-processing stage之间,它是可选的不是必要的.GS的输入是单个primiti ...