博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android--多线程之AsyncTask
阅读量:5290 次
发布时间:2019-06-14

本文共 9150 字,大约阅读时间需要 30 分钟。

前言

  本片博客将介绍AsyncTask的使用,之前有介绍过线程和进程。而在AsyncTask中,运行在用户界面中,执行异步操作,并且把执行结果发布在UI线程上,且也不需要处理线程和Handler。在本篇博客里,将会讲解到AsyncTask的基本介绍,以及如何使用,最后会以一个简单的Demo讲解AsyncTask的使用。

 

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必须遵循以下规则:

  • AsyncTask必须声明在UI线程上。
  • AsyncTask必须在UI线程上实例化。
  • 必须通过execute()方法执行任务。
  • 不可以直接调用onPreExecute()、onPostExecute(Resut)、doInBackground(Params...)、onProgressUpdate(Progress...)方法。
  • 可以设置任务只执行一次,如果企图再次执行会报错。

示例

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

  实现代码:

1 package com.bgxt.datatimepickerdemo; 2  3 import org.apache.http.HttpEntity; 4 import org.apache.http.HttpResponse; 5 import org.apache.http.client.HttpClient; 6 import org.apache.http.client.methods.HttpGet; 7 import org.apache.http.impl.client.DefaultHttpClient; 8 import org.apache.http.util.EntityUtils; 9 10 import android.app.Activity;11 import android.app.ProgressDialog;12 import android.graphics.Bitmap;13 import android.graphics.BitmapFactory;14 import android.os.AsyncTask;15 import android.os.Bundle;16 import android.view.View;17 import android.widget.Button;18 import android.widget.ImageView;19 20 public class AsyncTaskActivity1 extends Activity {21     private Button btnDown;22     private ImageView ivImage;23     private static String image_path = "http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg";24     private ProgressDialog dialog;25 26     @Override27     protected void onCreate(Bundle savedInstanceState) {28         // TODO Auto-generated method stub29         super.onCreate(savedInstanceState);30         setContentView(R.layout.asynctask_activity);31 32         btnDown = (Button) findViewById(R.id.btnDown);33         ivImage = (ImageView) findViewById(R.id.ivSinaImage);34         35         // 声明一个等待框以提示用户等待36         dialog=new ProgressDialog(this);37         dialog.setTitle("提示信息");38         dialog.setMessage("正在下载,请稍后...");39         40         btnDown.setOnClickListener(new View.OnClickListener() {41 42             @Override43             public void onClick(View v) {44                 // 执行一个异步任务,并把图片地址以参数的形式传递进去45                 new MyTask().execute(image_path);46             }47         });48     }49 50     // 以String类型的参数,Void表示没有进度信息,Bitmap表示异步任务返回一个位图51     public class MyTask extends AsyncTask
{52 // 表示任务执行之前的操作53 @Override54 protected void onPreExecute() {55 super.onPreExecute();56 //显示等待框57 dialog.show();58 }59 60 //主要是完成耗时操作61 @Override62 protected Bitmap doInBackground(String... params) {63 HttpClient httpClient=new DefaultHttpClient();64 HttpGet httpGet=new HttpGet(params[0]);65 Bitmap bitmap=null;66 try {67 //从网络上下载图片68 HttpResponse httpResponse =httpClient.execute(httpGet);69 if(httpResponse.getStatusLine().getStatusCode()==200){70 HttpEntity httpEntity = httpResponse.getEntity();71 byte[] data=EntityUtils.toByteArray(httpEntity);72 bitmap=BitmapFactory.decodeByteArray(data, 0, data.length); 73 }74 } catch (Exception e) {75 e.printStackTrace();76 }77 return bitmap;78 }79 80 //完成更新UI操作81 @Override82 protected void onPostExecute(Bitmap result) {83 // TODO Auto-generated method stub84 super.onPostExecute(result);85 //设置ImageView的显示图片86 ivImage.setImageBitmap(result);87 // 销毁等待框88 dialog.dismiss();89 }90 91 }92 }

  效果展示:

  

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

  实现代码:

1 package com.bgxt.datatimepickerdemo;  2   3 import java.io.ByteArrayOutputStream;  4 import java.io.InputStream;  5   6 import org.apache.http.HttpResponse;  7 import org.apache.http.client.HttpClient;  8 import org.apache.http.client.methods.HttpGet;  9 import org.apache.http.impl.client.DefaultHttpClient; 10  11 import android.app.Activity; 12 import android.app.ProgressDialog; 13 import android.graphics.Bitmap; 14 import android.graphics.BitmapFactory; 15 import android.os.AsyncTask; 16 import android.os.Bundle; 17 import android.view.View; 18 import android.widget.Button; 19 import android.widget.ImageView; 20  21 public class AsyncTaskActivity2 extends Activity { 22     private Button btnDown; 23     private ImageView ivImage; 24     private static String image_path = "http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg"; 25     private ProgressDialog dialog; 26  27     @Override 28     protected void onCreate(Bundle savedInstanceState) { 29         super.onCreate(savedInstanceState); 30         setContentView(R.layout.asynctask_activity); 31         btnDown = (Button) findViewById(R.id.btnDown); 32         ivImage = (ImageView) findViewById(R.id.ivSinaImage); 33  34         dialog = new ProgressDialog(this); 35         dialog.setTitle("提示"); 36         dialog.setMessage("正在下载,请稍后..."); 37         dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 38         dialog.setCancelable(false); 39  40         btnDown.setOnClickListener(new View.OnClickListener() { 41  42             @Override 43             public void onClick(View v) { 44                 //  执行异步任务 45                 new MyTask().execute(image_path); 46             } 47         }); 48     } 49  50     public class MyTask extends AsyncTask
{ 51 @Override 52 protected void onPreExecute() { 53 super.onPreExecute(); 54 dialog.show(); 55 } 56 57 @Override 58 protected void onProgressUpdate(Integer... values) { 59 super.onProgressUpdate(values); 60 // 设置进度对话框的进度值 61 dialog.setProgress(values[0]); 62 } 63 64 @Override 65 protected void onPostExecute(Bitmap result) { 66 super.onPostExecute(result); 67 dialog.dismiss(); 68 ivImage.setImageBitmap(result); 69 } 70 71 @Override 72 protected Bitmap doInBackground(String... params) { 73 Bitmap bitmap = null; 74 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 75 InputStream inputStream = null; 76 try { 77 HttpClient httpClient = new DefaultHttpClient(); 78 HttpGet httpGet = new HttpGet(params[0]); 79 HttpResponse httpResponse = httpClient.execute(httpGet); 80 if (httpResponse.getStatusLine().getStatusCode() == 200) { 81 inputStream = httpResponse.getEntity().getContent(); 82 long file_length = httpResponse.getEntity() 83 .getContentLength(); 84 int len = 0; 85 byte[] data = new byte[1024]; 86 int total_length = 0; 87 // 以字节的方式读取图片数据 88 while ((len = inputStream.read(data)) != -1) { 89 total_length += len; 90 // 计算进度 91 int values = (int) ((total_length / (float) file_length) * 100); 92 // 发布进度信息 93 publishProgress(values); 94 outputStream.write(data, 0, len); 95 } 96 byte[] result=outputStream.toByteArray(); 97 bitmap=BitmapFactory.decodeByteArray(result, 0, result.length); 98 } 99 } catch (Exception e) {100 e.printStackTrace();101 } finally {102 try {103 if (inputStream != null) {104 inputStream.close();105 }106 } catch (Exception e2) {107 }108 }109 return bitmap;110 }111 }112 }

  实现效果:

  

 

 

转载于:https://www.cnblogs.com/plokmju/p/android_AsyncTask.html

你可能感兴趣的文章
算法笔记--基础数学知识
查看>>
Extjs Dom
查看>>
初始化linux部署tomcat
查看>>
Predictive Analytics for Business
查看>>
Python中常用的模块(OS模块)
查看>>
Why should a self-implemented getter retain and autorelease the returned object
查看>>
altera小实验——第一个demo指导书
查看>>
强化学习1
查看>>
NSArray的sorting排序
查看>>
docker建立和共享文件(服务器和docker之间的共享)
查看>>
全文检索技术---solr
查看>>
动态内存分配(Dynamic memory allocation)
查看>>
Java学习 第三章 java基础(一)
查看>>
C#网络编程数据传输中封装数据帧头的方法
查看>>
第一份offer
查看>>
RNN Train和Test Mismatch
查看>>
.net下各个数据类型所占用的字节
查看>>
“请求的操作无法在使用用户映射区域打开的文件上执行”问题处理
查看>>
微信公众平台接口API
查看>>
hdu 4493 Tutor
查看>>