实际开发过程中,我们难免会遇到需要异步操作的场景:
例如用户下载升级文件,要让用户能够看到下载进度,同时完成后能点击安装,那下载的过程就是在另一个线程中完成,同时进度的显示则是要实时通知到UI主线程中的。AsyncTask来实现。
照旧先上代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 private  class  DownloadFileTask  extends  AsyncTask <String ,Double ,Double >                  @Override          protected  void  onPreExecute ()               LogUtils.i(TAG, "onPreExecute" );             super .onPreExecute();         }                  @Override          protected  Double doInBackground (String... params)               LogUtils.i(TAG, "doInBackground param:"  + params[0 ] + ","  + params[1 ] + ","  + params[2 ]                     + ","  + params[3 ]);       		             publishProgress(你自己的获取到的进度值);                          double  time_interval =  CommonUtils.downloadFileFromURL(params[1 ],params[2 ],params[3 ]);             return  time_interval;         }                  @Override          protected  void  onProgressUpdate (Double... progresses)               Log.i(TAG, "onProgressUpdate(Progress... progresses) called" );             super .onProgressUpdate();         }                  @Override          protected  void  onPostExecute (Double result)               Log.d(TAG, "onPostExecute result="  + result);         } 
以上的代码是一个最基本、最简单的没有经过太多处理的AsyncTask类,我们来分别详细看一下关于这个类的说明。
如何调用 
我们可以看到在AsyncTask类后是有三种泛型类型,分别代表“启动任务执行的输入参数” 、“后台任务执行的进度” 、“后台计算结果的类型” 。在特定场合下,并不是所有类型都被使用,如果没有被使用,可以用java.lang.Void类型代替;
通过调用new DownloadConfigureFile.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行,其中可以输入多个参数。
参数个数和类型看我们每个人的程序实际需要来完成了。比如我的程序中,CommonUtils.downloadFileFromURL(params[1],params[2],params[3])方法需要3个参数,那么我要在UI主线程中启动AsyncTask异步线程,就要这样写:new DownloadFileTask().execute("2",download_url,"FILE","PATH");
 
onPreExecute 方法 正如我在注释中写到的内容一样:本方法主要用于异步动作执行之前,一般用来处理UI,例如显示提示框等。
doInBackground 方法 注意这个方法是有返回值的,返回值的类型和AsyncTask泛型中的第3个参数类型保持一致。从本方法的字面上我们也能很清楚地了解到,这个方法就是用于在后台执行任务的,它可以随时在UI界面上做提醒,相应的动作可以通过调用publishProgress方法来实现,方法中传入的值会被onProgressUpdate接收到,同时在执行完之后,返回的值会被onPostExecute接收并处理。CommonUtils.downloadFileFromURL()方法的原代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49     public  static  double  downloadFileFromURL (String url_address, String filename, String local_path)       {                 File file_dir = context.getDir(local_path,Context.MODE_PRIVATE);                  File file = new  File(file_dir,filename);                  URL url;                  double  time_interval;         try  {             url = new  URL(url_address);             long  start_time = System.currentTimeMillis();             URLConnection url_conn = url.openConnection();             url_conn.setReadTimeout(5000 );             url_conn.setConnectTimeout(5000 );             InputStream input_stream = url_conn.getInputStream();             BufferedInputStream buffer_input_stream = new  BufferedInputStream(input_stream);                          ByteArrayBuffer byte_array_buff = new  ByteArrayBuffer(1024 *1024 );             int  current;             while ((current = buffer_input_stream.read()) != -1 ) {                 byte_array_buff.append((byte ) current);             }             FileOutputStream file_output_stream = new  FileOutputStream(file);             file_output_stream.write(byte_array_buff.toByteArray());             file_output_stream.flush();             file_output_stream.close();             time_interval = (System.currentTimeMillis() - start_time)/1000.0 ;             LogUtils.i("文件下载成功" , "耗时"  + (System.currentTimeMillis() - start_time) + "毫秒" );             return  time_interval;         } catch (IOException e) {             e.printStackTrace();             return  -1 ;         }     } 
onProgressUpdate 和 onPostExecute 这两个方法也能从字面上理解出来,一个是进度的更新,一个是完成之后的更新。这里就不再展开罗列了。