asyncktask详解

来源:互联网 发布:js canvas 动画库 编辑:程序博客网 时间:2024/06/01 18:55

AsyncTask允许您执行异步工作在你的用户界面。它执行阻塞操作在一个工作线程,然后在UI线程上公布结果,不需要你自己处理线程和/或处理程序

使用它,您必须子类AsyncTask,实现doInBackground()回调方法,它运行在一个后台线程池。更新你的UI,你应该实现onPostExecute(),提供来自doInBackground()和结果在UI线程中运行,所以您可以安全地更新UI。然后您可以运行任务从UI线程通过调用execute()

AsyncTask使适当的和容易使用的UI线程。这个类可以在UI线程上执行后台操作和发布结果无需操纵线程和/或处理程序。

AsyncTask被设计成一个助手类线程和处理程序和不构成通用线程框架。asynctask理想情况下应该用于短操作(最多几秒钟)。如果你需要保持线程运行很长一段时间,强烈推荐您使用各种java.util提供的api。并发包如遗嘱执行人,ThreadPoolExecutor FutureTask。

异步任务被定义为一个计算,运行在一个后台线程,其结果发表在UI线程上。异步任务被定义为3泛型类型,称为Params,进展和结果,和4步骤,称为onPreExecute doInBackground,onProgressUpdate onPostExecute。

AsyncTask定义了三种泛型类型 Params,Progress和Result。

  • Params 启动任务执行的输入参数,比如HTTP请求的URL。
  • Progress 后台任务执行的百分比。
  • Result 后台执行任务最终返回的结果,比如String。

有必要的话你还得重写以下这三个方法,但不是必须的:

  • onProgressUpdate(Progress…)   可以使用进度条增加用户体验度。 此方法在主线程执行,用于显示任务执行的进度。
  • onPreExecute()        这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
  • onCancelled()             用户调用取消时,要做的操作

使用AsyncTask类,以下是几条必须遵守的准则:

  • Task的实例必须在UI thread中创建;
  • execute方法必须在UI thread中调用;
  • 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
  • 该task只能被执行一次,否则多次调用时将会出现异常;

一个超简单的理解 AsyncTask 的例子:

main.xml

[java] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7.     <TextView    
  8.     android:id="@+id/textView01"  
  9.     android:layout_width="fill_parent"   
  10.     android:layout_height="wrap_content"   
  11.     />  
  12.    <ProgressBar   
  13.    android:id="@+id/progressBar02"  
  14.     android:layout_width="fill_parent"   
  15.     android:layout_height="wrap_content"   
  16.     style="?android:attr/progressBarStyleHorizontal"   
  17.     />  
  18.     <Button  
  19.     android:id="@+id/button03"  
  20.     android:layout_width="fill_parent"   
  21.     android:layout_height="wrap_content"   
  22.     android:text="更新progressbar"  
  23.     />  
  24. </LinearLayout>  


MainActivity.java

[html] view plaincopy
  1. package vic.wong.main;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.view.View;  
  6. import android.view.View.OnClickListener;  
  7. import android.widget.Button;  
  8. import android.widget.ProgressBar;  
  9. import android.widget.TextView;  
  10.   
  11. public class MainActivity extends Activity {  
  12.     private Button button;  
  13.     private ProgressBar progressBar;  
  14.     private TextView textView;  
  15.       
  16.     @Override  
  17.     public void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.main);  
  20.           
  21.         button = (Button)findViewById(R.id.button03);  
  22.         progressBar = (ProgressBar)findViewById(R.id.progressBar02);  
  23.         textView = (TextView)findViewById(R.id.textView01);  
  24.           
  25.         button.setOnClickListener(new OnClickListener() {  
  26.               
  27.             @Override  
  28.             public void onClick(View v) {  
  29.                 ProgressBarAsyncTask asyncTask = new ProgressBarAsyncTask(textView, progressBar);  
  30.                 asyncTask.execute(1000);  
  31.             }  
  32.         });  
  33.     }  
  34. }  

 


NetOperator.java

[html] view plaincopy
  1. package vic.wong.main;  
  2.   
  3.   
  4. //模拟网络环境  
  5. public class NetOperator {  
  6.       
  7.     public void operator(){  
  8.         try {  
  9.             //休眠1秒  
  10.             Thread.sleep(1000);  
  11.         } catch (InterruptedException e) {  
  12.             // TODO Auto-generated catch block  
  13.             e.printStackTrace();  
  14.         }  
  15.     }  
  16.   
  17. }  

 


ProgressBarAsyncTask .java 

[html] view plaincopy
  1. package vic.wong.main;  
  2. import android.os.AsyncTask;  
  3. import android.widget.ProgressBar;  
  4. import android.widget.TextView;  
  5.   
  6. /**  
  7.  * 生成该类的对象,并调用execute方法之后  
  8.  * 首先执行的是onProExecute方法  
  9.  * 其次执行doInBackgroup方法  
  10.  *  
  11.  */  
  12. public class ProgressBarAsyncTask extends AsyncTask<Integer, Integer, String> {  
  13.   
  14.     private TextView textView;  
  15.     private ProgressBar progressBar;  
  16.       
  17.       
  18.     public ProgressBarAsyncTask(TextView textView, ProgressBar progressBar) {  
  19.         super();  
  20.         this.textView = textView;  
  21.         this.progressBar = progressBar;  
  22.     }  
  23.   
  24.   
  25.     /**  
  26.      * 这里的Integer参数对应AsyncTask中的第一个参数   
  27.      * 这里的String返回值对应AsyncTask的第三个参数  
  28.      * 该方法并不运行在UI线程当中,主要用于异步操作,所有在该方法中不能对UI当中的空间进行设置和修改  
  29.      * 但是可以调用publishProgress方法触发onProgressUpdate对UI进行操作  
  30.      */  
  31.     @Override  
  32.     protected String doInBackground(Integer... params) {  
  33.       //  NetOperator netOperator = new NetOperator();  
  34.       //  int i = 0;  
  35.       //  for (i = 10; i <= 100; i+=10) {  
  36.       //      netOperator.operator();  
  37.       //      publishProgress(i);  
  38.       //  }  
  39.       //  return i + params[0].intValue() + "";  
  40.       Bitmap bitmap = null;
  41.       ByteArrayOutputStream outputStream = new ByteArrayOututStream();
  42.       InputStream inputStream = null;// 在finaly里面关闭
  43.       HttpClient httpClient = new DefaultHttpClient();
  44.       HttpGet httpGet = new HttpGet(param[0]);
  45.       HttpResponse httpresponse = httpClient.execute(httpGet);
  46.       if(httpresponse.getStatuesLine.getStatusCode==200)
  47.       {
  48. inputStream = httpresponse.getEntity.getContent();
  49. // 先要获取文件的总长度
  50. long file_length = httpresponse.getEntity.getContentLength();
  51.         int len = 0;
  52.         byte[] data = new byte[1024];
  53. int total_length = 0;
  54. while((len=inputstream.read(data))!=-1)
  55. {
  56. total_length +=len;
  57. int value = ((total_length/file_length)*100);
  58. publishProgressUpdate(value);
  59. outputStream.write(data,0,len);
  60. }
  61. byte[] result = outputStream.toByteArray();
  62. bitmap = BItmapFactory.decodeByteArray(result,0,result.length)
  63.       }
  64.       
  1.     }  
  2.   
  3.   
  4.     /**  
  5.      * 这里的String参数对应AsyncTask中的第三个参数(也就是接收doInBackground的返回值)  
  6.      * 在doInBackground方法执行结束之后在运行,并且运行在UI线程当中 可以对UI空间进行设置  
  7.      */  
  8.     @Override  
  9.     protected void onPostExecute(String result) {  
  10.         textView.setText("异步操作执行结束" + result);  
  11.     }  
  12.   
  13.   
  14.     //该方法运行在UI线程当中,并且运行在UI线程当中 可以对UI空间进行设置  
  15.     @Override  
  16.     protected void onPreExecute() {  
  17.         textView.setText("开始执行异步线程");  
  18.     }  
  19.   
  20.   
  21.     /**  
  22.      * 这里的Intege参数对应AsyncTask中的第二个参数  
  23.      * 在doInBackground方法当中,,每次调用publishProgress方法都会触发onProgressUpdate执行  
  24.      * onProgressUpdate是在UI线程中执行,所有可以对UI空间进行操作  
  25.      */  
  26.     @Override  
  27.     protected void onProgressUpdate(Integer... values) {  
  28.         int vlaue = values[0];  
  29.         progressBar.setProgress(vlaue);  
  30.     }  
  31.   
  32.       
  33.       
  34.       
  35.   
  36. }  


0 0
原创粉丝点击