展会信息港展会大全

android开发多线程之AsyncTask
来源:互联网   发布日期:2016-01-14 12:39:59   浏览:1491次  

导读:AsyncTask AsyncTask,异步任务,可以简单进行异步操作,并把执行结果发布到UI主线程。AsyncTask是一个抽象类,它的内部其实也是结合 了Thread和Handler来实现异步线程操作,但是它形成了一个通用线程框架, ...

AsyncTask

AsyncTask,异步任务,可以简单进行异步操作,并把执行结果发布到UI主线程。AsyncTask是一个抽象类,它的内部其实也是结合 了Thread和Handler来实现异步线程操作,但是它形成了一个通用线程框架,更清晰简单。AsyncTask应该被用于比较简短的操作(最多几秒 钟)。如果需要保持长时间运行的线程,可以使用ThreadPooExecutor或者FutureTask,关于这两个类的内容,以后再介绍,本片博客 主要介绍AsyncTask。

AsyncTask被定义为一个操作,运行在一个后台线程中,其结果被发布在UI线程上。它的异步工作的参数与返回值被泛型的三个参数指 定:Params、Progress、Result。AsyncTask将经历4个步骤:onPreExecute、doInBackground、 onProgressUpdate、onPostExecute。下面详细讲解这三个参数与四个步骤:

三个泛型参数:

Params:被发送到执行任务的参数类型。

Progress:进度的类型,发送后台的计算进度到UI线程类型。

Result:异步任务的返回结果类型。

一个异步任务将经历四个阶段:

onPreExecute():执行在UI线程上调用执行任务之前,一般用于设置任务。

doInBackground(Params...):主要是用来执行异步任务的耗时操作,可以在这个方法中通过 publishProgress()方法发布进度信息,并在执行完成之后,返回执行结果。

onProgreddUpdate(Progress...):在UI线程上接受doInBackground()传递过来的进度信息, 并在UI线程上展示进度信息,它执行的时机是不确定的。

onPostExecute(Result):在UI线程上操作doInBackground()执行的返回值。

上面介绍的四个步骤的示意图:

AsyncTask取消任务

在程序的任何位置,都可以通过cancel(boolean)方法进行取消任务,当取消任务之后,会改变isCancelled()的返回值, 使其返回true。之后会调用onCancelled(Object)方法,替代onPostExecute()得到doInBackground()的 返回结果。在运行中,可以经常通过isCancelled()方法查看任务是否被取消。

AsyncTask的使用规则

使用AsyncTask必须遵循以下规则:

%20%20%20%20

AsyncTask必须声明在UI线程上。

%20%20%20%20

AsyncTask必须在UI线程上实例化。

%20%20%20%20

必须通过execute()方法执行任务。

%20%20%20%20

不可以直接调用onPreExecute()、onPostExecute(Resut)、 doInBackground(Params...)、onProgressUpdate(Progress...)方法。

%20%20%20%20

可以设置任务只执行一次,如果企图再次执行会报错。

示例

一个简单的示例,通过AsyncTask下载一个网络上的图片,下载的时候展示一个等待框,并显示在一个ImageView中。

实现代码:

%201%20package%20com.bgxt.datatimepickerdemo;

%202%20

%203%20import%20org.apache.http.HttpEntity;

%204%20import%20org.apache.http.HttpResponse;

%205%20import%20org.apache.http.client.HttpClient;

%206%20import%20org.apache.http.client.methods.HttpGet;

%207%20import%20org.apache.http.impl.client.DefaultHttpClient;

%208%20import%20org.apache.http.util.EntityUtils;

%209%20

10%20import%20android.app.Activity;

11%20import%20android.app.ProgressDialog;

12%20import%20android.graphics.Bitmap;

13%20import%20android.graphics.BitmapFactory;

14%20import%20android.os.AsyncTask;

15%20import%20android.os.Bundle;

16%20import%20android.view.View;

17%20import%20android.widget.Button;

18%20import%20android.widget.ImageView;

19%20

20%20public%20class%20AsyncTaskActivity1%20extends%20Activity%20{

21%20%20%20%20%20private%20Button%20btnDown;

22%20%20%20%20%20private%20ImageView%20ivImage;

23%20%20%20%20%20private%20static%20String%20image_path%20=%20"http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";

24private ProgressDialog dialog;

25

26@Override

27protected void onCreate(Bundle savedInstanceState) {

28// TODO Auto-generated method stub

29super.onCreate(savedInstanceState);

30setContentView(R.layout.asynctask_activity);

31

32btnDown = (Button) findViewById(R.id.btnDown);

33ivImage = (ImageView) findViewById(R.id.ivSinaImage);

34

35// 声明一个等待框以提示用户等待

36dialog=new ProgressDialog(this);

37dialog.setTitle("提示信息");

38dialog.setMessage("正在下载,请稍后...");

39

40btnDown.setOnClickListener(new View.OnClickListener() {

41

42@Override

43public void onClick(View v) {

44// 执行一个异步任务,并把图片地址以参数的形式传递进去

45new MyTask().execute(image_path);

46}

47});

48}

49

50// 以String类型的参数,Void表示没有进度信息,Bitmap表示异步任务返回一个位图

51public class MyTask extends AsyncTask<String, Void, Bitmap> {

52// 表示任务执行之前的操作

53@Override

54protected void onPreExecute() {

55super.onPreExecute();

56//显示等待框

57dialog.show();

58}

59

60//主要是完成耗时操作

61@Override

62protected Bitmap doInBackground(String... params) {

63HttpClient httpClient=new DefaultHttpClient();

64HttpGet httpGet=new HttpGet(params[0]);

65Bitmap bitmap=null;

66try {

67//从网络上下载图片

68HttpResponse httpResponse =httpClient.execute(httpGet);

69if(httpResponse.getStatusLine().getStatusCode()==200){

70HttpEntity httpEntity = httpResponse.getEntity();

71byte[] data=EntityUtils.toByteArray(httpEntity);

72bitmap=BitmapFactory.decodeByteArray(data, 0, data.length);

73}

74} catch (Exception e) {

75e.printStackTrace();

76}

77return bitmap;

78}

79

80//完成更新UI操作

81@Override

82protected void onPostExecute(Bitmap result) {

83// TODO Auto-generated method stub

84super.onPostExecute(result);

85//设置ImageView的显示图片

86ivImage.setImageBitmap(result);

87// 销毁等待框

88dialog.dismiss();

89}

90

91}

92 }

效果展示:

上面的Demo并没有用到进度的信息,下面再提供一个完整的AsyncTask的Demo,同样是下载一个图片,并且展示到一个 ImageView中,但是这里在下载的过程中增加一个进度条对话框,用于展示下载的进度。

实现代码:

%20%201%20package%20com.bgxt.datatimepickerdemo;

%20%202%20

%20%203%20import%20java.io.ByteArrayOutputStream;

%20%204%20import%20java.io.InputStream;

%20%205%20

%20%206%20import%20org.apache.http.HttpResponse;

%20%207%20import%20org.apache.http.client.HttpClient;

%20%208%20import%20org.apache.http.client.methods.HttpGet;

%20%209%20import%20org.apache.http.impl.client.DefaultHttpClient;

%2010%20

%2011%20import%20android.app.Activity;

%2012%20import%20android.app.ProgressDialog;

%2013%20import%20android.graphics.Bitmap;

%2014%20import%20android.graphics.BitmapFactory;

%2015%20import%20android.os.AsyncTask;

%2016%20import%20android.os.Bundle;

%2017%20import%20android.view.View;

%2018%20import%20android.widget.Button;

%2019%20import%20android.widget.ImageView;

%2020%20

%2021%20public%20class%20AsyncTaskActivity2%20extends%20Activity%20{

%2022%20%20%20%20%20private%20Button%20btnDown;

%2023%20%20%20%20%20private%20ImageView%20ivImage;

%2024%20%20%20%20%20private%20static%20String%20image_path%20=%20"http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";

25private ProgressDialog dialog;

26

27@Override

28protected void onCreate(Bundle savedInstanceState) {

29super.onCreate(savedInstanceState);

30setContentView(R.layout.asynctask_activity);

31btnDown = (Button) findViewById(R.id.btnDown);

32ivImage = (ImageView) findViewById(R.id.ivSinaImage);

33

34dialog = new ProgressDialog(this);

35dialog.setTitle("提示");

36dialog.setMessage("正在下载,请稍后...");

37dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

38dialog.setCancelable(false);

39

40btnDown.setOnClickListener(new View.OnClickListener() {

41

42@Override

43public void onClick(View v) {

44//执行异步任务

45new MyTask().execute(image_path);

46}

47});

48}

49

50public class MyTask extends AsyncTask<String, Integer, Bitmap> {

51@Override

52protected void onPreExecute() {

53super.onPreExecute();

54dialog.show();

55}

56

57@Override

58protected void onProgressUpdate(Integer... values) {

59super.onProgressUpdate(values);

60// 设置进度对话框的进度值

61dialog.setProgress(values[0]);

62}

63

64@Override

65protected void onPostExecute(Bitmap result) {

66super.onPostExecute(result);

67dialog.dismiss();

68ivImage.setImageBitmap(result);

69}

70

71@Override

72protected Bitmap doInBackground(String... params) {

73Bitmap bitmap = null;

74ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

75InputStream inputStream = null;

76try {

77HttpClient httpClient = new DefaultHttpClient();

78HttpGet httpGet = new HttpGet(params[0]);

79HttpResponse httpResponse = httpClient.execute(httpGet);

80if (httpResponse.getStatusLine().getStatusCode() == 200) {

81inputStream = httpResponse.getEntity().getContent();

82long file_length = httpResponse.getEntity()

83.getContentLength();

84int len = 0;

85byte[] data = new byte[1024];

86int total_length = 0;

87// 以字节的方式读取图片数据

88while ((len = inputStream.read(data)) != -1) {

89total_length += len;

90// 计算进度

91int values = (int) ((total_length / (float) file_length) * 100);

92// 发布进度信息

93publishProgress(values);

94outputStream.write(data, 0, len);

95}

96byte[] result=outputStream.toByteArray();

97bitmap=BitmapFactory.decodeByteArray(result, 0, result.length);

98}

99} catch (Exception e) {

100e.printStackTrace();

101} finally {

102try {

103if (inputStream != null) {

104inputStream.close();

105}

106} catch (Exception e2) {

107}

108}

109return bitmap;

110}

111}

112 }

实现效果:

赞助本站

人工智能实验室

相关热词: 多线程 AsyncTask android

AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港