AsyncTask是android 1.5提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程。
优点:简单快捷、过程可控
AsyncTask的使用步骤:
1 添加一个类,继承AsyncTask,并设置相应参数
2 重写四个方法
onPreExecute() 该方法将在执行后台操作前会被UI线程调用。可以在该方法中做一些准备工作,如在界面
上显示一个进度对话框(ProgressDialog)
doInBackground(Params...) 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。
负责执行耗时操作。可以在该方法中调用publishProgress方法来通知UI线程更新实时的任务进度
onProgressUpdate(Progress...)在publishProgress方法被调用后,UI 线程将调用本方法更新进度
onPostExecute(Result)在doInBackground 执行完成后,本方法将被UI 线程调用,在此方法中更新UI界面
AsyncTask的参数说明:
AsyncTask是一个抽象类. 它需要三种泛型类型的参数,Params,Progress和Result
Params 启动任务执行的输入参数,比如HTTP请求的URL。 一般用String类型
Progress 后台任务执行的百分比。 一般用Integer类型,不需要更新进度的时候用Void(大写字母V)
Result 后台执行任务最终返回的结果,一般用byte[ ]或者String
案例一:模拟下载
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;
/**
* 异步任务类 泛型参数 1 Params 参数 String(网址) 2 Progress 进度 Integer 3 Result 结果 byte[]
* String Bitmap List<String>
*
* @author Administrator
*
*/
public class LoadAsyncTask extends AsyncTask<String, Integer, String> {
// 异步任务操作的控件
private ProgressBar pb1;
private TextView tv_info;
public LoadAsyncTask(ProgressBar pb1, TextView tv_info) {
super();
this.pb1 = pb1;
this.tv_info = tv_info;
}
/**
* 预先执行的方法 准备工作 主线程执行
*/
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
Log.i("LoadAsyncTask", "onPreExecute执行了......"
+ Thread.currentThread().getName());
tv_info.setText("开始下载");
pb1.setMax(100);
}
/**
* 后台执行的方法 子线程(工作线程worker thread)执行
*/
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
Log.i("LoadAsyncTask", "doInBackground执行了......"
+ Thread.currentThread().getName());
for (int i = 0; i <= 100; i++) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 发布进度i(每次都放到values数组中的第一个元素)
publishProgress(i);
}
return "OK";
}
/**
* 进度更新方法(主线程执行)
*/
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
Log.i("LoadAsyncTask", "onProgressUpdate执行了......"
+ Thread.currentThread().getName());
pb1.setProgress(values[0]);
tv_info.setText(values[0] + "%");
}
/**
* 处理结果的方法(主线程执行)
*/
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Log.i("LoadAsyncTask", "onPostExecute执行了......"
+ Thread.currentThread().getName());
tv_info.setText("下载完毕" + result);
}
}
public class MainActivity extends Activity {
private ProgressBar pb1;
private TextView tv_info;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化控件
pb1 = (ProgressBar) this.findViewById(R.id.pb1);
tv_info = (TextView) this.findViewById(R.id.tv_info);
}
public void btn_load(View view) {
// 执行异步任务
// 1创建异步任务对象
LoadAsyncTask task = new LoadAsyncTask(pb1, tv_info);
// 2执行
task.execute("网址");
}
}
运行结果:
案例二:利用异步任务,从网络上读取一个网页的内容并显示在TextView中
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Http工具类
*
* @author Administrator
*
*/
public class HttpUtils {
/**
* 网络请求
*
* @param urlpath
* @return
*/
public static byte[] request(String urlpath) {
ByteArrayOutputStream baos = null;
try {
// 1创建URL对象
URL url = new URL(urlpath);
// 2调用openConnnection方法返回UrlConnection
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
// 3设置请求参数
// 连接超时时间
connection.setConnectTimeout(10000);
// 读取超时时间
connection.setReadTimeout(10000);
// 4连接
connection.connect();
// 5处理请求结果
if (connection.getResponseCode() == 200) {
InputStream is = connection.getInputStream();
baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024 * 4];
int len = 0;
while ((len = is.read(buf)) != -1) {
baos.write(buf, 0, len);
}
is.close();
return baos.toByteArray();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
import java.io.UnsupportedEncodingException;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.TextView;
import android.widget.Toast;
import com.qf.day07_asynctaskdemo2.utils.HttpUtils;
public class LoadpageAsyncTask extends AsyncTask<String, Void, String> {
// 文本框
private TextView tv_content;
// 进度对话框
private ProgressDialog pd;
// 上下文
private Context context;
public LoadpageAsyncTask(TextView tv_content, Context context) {
super();
this.tv_content = tv_content;
this.context = context;
// 初始化pd
pd = new ProgressDialog(context);
// 设置属性
pd.setMessage("正在玩命加载中...");
// 设置标题
pd.setTitle("提示");
// 设置图标
pd.setIcon(R.drawable.ic_launcher);
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
// 显示对话框
pd.show();
}
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
// 网址
String url = params[0];
byte[] b = HttpUtils.request(url);
String str = null;
if (b != null) {
try {
str = new String(b, "utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return str;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (result != null) {
tv_content.setText(result);
} else {
Toast.makeText(context, "网络有异常....", 0).show();
}
// 关闭对话框
pd.dismiss();
}
}
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView tv_content;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_content = (TextView) this.findViewById(R.id.tv_content);
}
public void btn_loadpage(View view) {
// 1创建异步任务对象
LoadpageAsyncTask task = new LoadpageAsyncTask(tv_content, this);
// 2执行
task.execute("http://m.baidu.com");
}
}
运行结果:
案例三:利用异步任务从网络上读取一个图片并显示到ImageView中
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;
import android.widget.Toast;
import com.qf.day07_asynctaskdemo3.utils.HttpUtils;
public class LoadImageAsyncTask extends AsyncTask<String, Void, byte[]> {
// 控件
private ImageView iv;
private Context context;
private ProgressDialog pd;
public LoadImageAsyncTask(ImageView iv, Context context) {
super();
this.iv = iv;
this.context = context;
this.pd = new ProgressDialog(context);
pd.setMessage("玩命加载中....");
pd.setTitle("提示");
pd.setIcon(R.drawable.ic_launcher);
// 阻止返回键关闭对话框
pd.setCancelable(false);
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
pd.show();
}
@Override
protected byte[] doInBackground(String... params) {
// TODO Auto-generated method stub
return HttpUtils.request(params[0]);
}
@Override
protected void onPostExecute(byte[] result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (result != null) {
// 把图片字节转化成图片
Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0,
result.length);
// 设置图片框
iv.setImageBitmap(bitmap);
} else {
Toast.makeText(context, "网络有异常....", 0).show();
}
// 关闭对话框
pd.dismiss();
}
}
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) this.findViewById(R.id.iv);
}
public void btn_loadimage(View view) {
// 1创建异步任务对象
LoadImageAsyncTask task = new LoadImageAsyncTask(iv, this);
// 2执行
task.execute("http://h.hiphotos.baidu.com/image/pic/item/5bafa40f4bfbfbed9416b3957cf0f736aec31f88.jpg");
}
}
运行结果:
案例四:获取网络JSON数据,并解析成List集合对象,填充到Spinner中
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* 把json字符串解析成集合
*
* @author Administrator
*
*/
public class JsonUtils {
/**
* 把json字符串解析成集合
*
* @param json
* @return
*/
public static List<String> getListFromJson(String json) {
List<String> list;
try {
JSONObject root = new JSONObject(json);
JSONArray array = root.getJSONArray("list");
list = new ArrayList<String>();
for (int i = 0; i < array.length(); i++) {
JSONObject obj = array.getJSONObject(i);
String name = obj.getString("name");
list.add(name);
}
return list;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
import java.io.UnsupportedEncodingException;
import java.util.List;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
import com.qf.day07_asynctaskdemo4.utils.HttpUtils;
import com.qf.day07_asynctaskdemo4.utils.JsonUtils;
public class LoadJsonAsyncTask extends AsyncTask<String, Void, List<String>> {
private Spinner sp_name;
private Context context;
public LoadJsonAsyncTask(Spinner sp_name, Context context) {
super();
this.sp_name = sp_name;
this.context = context;
}
@Override
protected List<String> doInBackground(String... params) {
// TODO Auto-generated method stub
byte[] b = HttpUtils.request(params[0]);
List<String> list = null;
if (b != null) {
try {
String json = new String(b, "utf-8");
list = JsonUtils.getListFromJson(json);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
}
return null;
}
@Override
protected void onPostExecute(List<String> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (result != null) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(context,
android.R.layout.simple_spinner_item, result);
sp_name.setAdapter(adapter);
} else {
Toast.makeText(context, "网络有异常....", 0).show();
}
}
}
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.Spinner;
public class MainActivity extends Activity {
private Spinner sp_name;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化控件
sp_name = (Spinner) this.findViewById(R.id.sp_name);
// 创建异步任务对象
LoadJsonAsyncTask task = new LoadJsonAsyncTask(sp_name, this);
task.execute("http://piao.163.com/m/movie/list.html?app_id=2&mobileType=iPhone&ver=2.5&channel=lede&deviceId=C1985DD9-0125-4AB5-B66B-B91A85824BBA&apiVer=11&city=110000");
}
}
运行结果:
案例五:获取网络XML数据,并解析成List集合对象,填充到AutoCompleteTextView中
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpUtils {
public static InputStream getStream(String urlStr){
try {
URL url = new URL(urlStr);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(10000);
connection.setReadTimeout(10000);
connection.connect();
if (connection.getResponseCode()==200) {
return connection.getInputStream();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
public class XmlUtils {
public static List<String> getData(InputStream is) {
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser parser = factory.newPullParser();
parser.setInput(is, "utf-8");
int type = parser.getEventType();
List<String> data = null;
while(type!=XmlPullParser.END_DOCUMENT){
switch (type) {
case XmlPullParser.START_TAG:
String tag = parser.getName();
if (tag.equals("fruit")) {
data = new ArrayList<String>();
}else if(tag.equals("item")){
String item = parser.nextText();
data.add(item);
}
break;
default:
break;
}
type=parser.next();
}
return data;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if (is!=null) {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
}
import java.io.InputStream;
import java.util.List;
import com.example.day07_asyntaskdemo5.utils.HttpUtils;
import com.example.day07_asyntaskdemo5.utils.XmlUtils;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Toast;
public class XmlLoadAsyncTask extends AsyncTask<String, Void, List<String>> {
private AutoCompleteTextView actv_fruit;
private Context context;
public XmlLoadAsyncTask(AutoCompleteTextView actv_fruit, Context context) {
super();
this.actv_fruit = actv_fruit;
this.context = context;
}
@Override
protected List<String> doInBackground(String... params) {
// TODO Auto-generated method stub
InputStream is=HttpUtils.getStream(params[0]);
if (is!=null) {
return XmlUtils.getData(is);
}
return null;
}
@Override
protected void onPostExecute(List<String> result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if (result!=null) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item,result);
actv_fruit.setAdapter(adapter);
}else {
Toast.makeText(context, "网络或解析异常....", 0).show();
}
}
}
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.AutoCompleteTextView;
public class MainActivity extends Activity {
private AutoCompleteTextView actv_fruit;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
actv_fruit = (AutoCompleteTextView) findViewById(R.id.actv_fruit);
XmlLoadAsyncTask task = new XmlLoadAsyncTask(actv_fruit, this);
task.execute("http://10.0.172.124:8080/DataServer/fruit.xml");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}