`
y150988451
  • 浏览: 195107 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

AsyncTask

阅读更多

平时我们在开发Android程序时遇到较耗时任务的处理,如I/O访问的数据库操作、网络访问等情况时造成UI假死等问题,通过 AsyncTask可以很好的解决这个问题,就今天以在Android中执行Downloader.downloadFile(url),可能会堵塞整个界面。显然这会影响用户体验,我们如何解决这个问题呢? 

  方法一、 

  创建一个新的线程执行我们的任务,使用Thread类,在 run(){}中写入任务代码,比如: 

  new Thread(new Runnable() { 

  public void run() { 

  Downloader.downloadFile(url); 

  } 

  }).start(); 

  但使用Thread会产生一些意想不到的问题,需要程序员用更多的代码手动的维护它。 

  方法二: Android SDK为我们提供了一个后台任务的处理工具AsyncTask。AsyncTask就是一个封装过的后台任务类顾名思义就是异步任务,方便我们维护,Android开发网提示这样的好处可以解决一些线程安全问题,AsyncTask直接继承于Object类,位置为 android.os.AsyncTask。要使用AsyncTask工作我们要提供三个泛型参数,并重载四个方法(至少重载一个)。 

  三个泛型: 

  Param ,任务执行器需要的数据类型 

  Progress 后台计算中使用的进度单位数据类型 

  Result 后台计算返回结果的数据类型 

  有些参数是可以设置为不使用的,只要传递为Void型即可,比如AsyncTask 

  四个步骤: 

  onPreExecute(),执行预处理,它运行于UI线程,可以为后台任务做一些准备工作,比如绘制一个进度条控件。 

  doInBackground(Params...),后台进程执行的具体计算在这里实现,doInBackground(Params...)是AsyncTask的关键,此方法必须重载。在这个方法内可以使用 publishProgress(Progress...)改变当前的进度值。 

  onProgressUpdate(Progress...),运行于UI线程。如果在doInBackground(Params...)中使用了publishProgress(Progress...),就会触发这个方法。在这里可以对进度条控件根据进度值做出具体的响应。 

  onPostExecute(Result),运行于UI线程,可以对后台任务的结果做出处理,结果就是doInBackground(Params...)的返回值。此方法也要经常重载,如果Result为null表明后台任务没有完成(被取消或者出现异常)。 


Java代码  收藏代码
  1. public class main extends Activity {  
  2.     ImageView imageView01;  
  3.     TextView textView;  
  4.     @Override  
  5.     public void onCreate(Bundle savedInstanceState) {  
  6.         super.onCreate(savedInstanceState);  
  7.         setContentView(R.layout.main);  
  8.   
  9.         textView = (TextView) this.findViewById(R.id.TextView01);  
  10.         imageView01 = (ImageView) this.findViewById(R.id.ImageView01);  
  11.         GetImage getImage = new GetImage();  
  12.         getImage.execute("http://hi.csdn.net/attachment/201010/27/0_1288149117Yk8W.gif");  
  13.     }  
  14.   
  15.     private class GetImage extends AsyncTask {  
  16.   
  17.         public GetImage() {  
  18.             super();  
  19.             // TODO Auto-generated constructor stub  
  20.         }  
  21.   
  22.         @Override  
  23.         protected void onCancelled() {  
  24.             Log.i("czb""onCancelled is running...");  
  25.   
  26.             super.onCancelled();  
  27.         }  
  28.   
  29.         @Override  
  30.         protected void onPostExecute(Object result) {  
  31.             /* 
  32.              * 此方法在主线程执行,任务执行的结果作为此方法的参数返回 
  33.              */  
  34.             Log.i("czb""onPostExecute is running...");  
  35.             Log.i("czb""result == null ? " + (result == null));  
  36.             imageView01.setImageBitmap((Bitmap)result);  
  37.               
  38.             super.onPostExecute(result);  
  39.         }  
  40.   
  41.         @Override  
  42.         protected void onPreExecute() {  
  43.             /* 
  44.              * 执行预处理,它运行于UI线程,可以为后台任务做一些准备工作,比如绘制一个进度条控件 
  45.              */  
  46.             Log.i("czb""onPreExecute is running...");  
  47.               
  48.             super.onPreExecute();  
  49.         }  
  50.   
  51.         @Override  
  52.         protected void onProgressUpdate(Object... values) {  
  53.             /* 
  54.              * 此方法在主线程执行,用于显示任务执行的进度。 
  55.              */  
  56.             Log.i("czb""onProgressUpdate is running...");  
  57.             // 由publishProgress传递的值  
  58.             Log.i("czb""values " + values[0]);  
  59.             super.onProgressUpdate(values);  
  60.         }  
  61.   
  62.         @Override  
  63.         protected Object doInBackground(Object... params) {  
  64.             /* 
  65.              * 此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。 
  66.              * 在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。 
  67.              */  
  68.             Log.i("czb""doInBackground is running...");  
  69.               
  70.             try {  
  71.                 Bitmap bitmap;  
  72.                 HttpClient client = new DefaultHttpClient();  
  73.                 // params[0]代表连接的url  
  74.                 URI uri = URI.create((String) params[0]);  
  75.                 HttpGet get = new HttpGet(uri);  
  76.                 HttpResponse response = client.execute(get);  
  77.                 HttpEntity entity = response.getEntity();  
  78.                 long length = entity.getContentLength();  
  79.                 Log.i("czb""  " + length);  
  80.                 InputStream in = entity.getContent();  
  81.                 if (in != null) {  
  82.                     ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  83.                     /*byte[] buf = new byte[128]; 
  84.                     int ch = -1; 
  85.                     int count = 0; 
  86.                     while ((ch = in.read(buf)) != -1) { 
  87.                         baos.write(buf, 0, ch); 
  88.                         count += ch; 
  89.                         if (length > 0) { 
  90.                             // 如果知道响应的长度,调用publishProgress()更新进度 
  91.                             // onProgressUpdate读取进度 
  92.                             publishProgress((int) ((count / (float) length) * 100)); 
  93.                         } 
  94.                         // 为了在模拟器中清楚地看到进度,让线程休眠100ms 
  95.                         //Thread.sleep(100); 
  96.                     }*/  
  97.                     bitmap = BitmapFactory.decodeStream(in);  
  98.                     in.close();  
  99.                     baos.close();  
  100.                     return bitmap;  
  101.                 }  
  102.             } catch (Exception e) {  
  103.                 e.printStackTrace();  
  104.             }  
  105.             return null;  
  106.         }  
  107.   
  108.     }  
  109. }  

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics