AsyncTask用法和异步加载图片
AsyncTask:是Android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程。
AsyncTask (异步任务),从字面上来说,就是在我们的UI主线程运行的时候,异步的完成一些操作。AsyncTask允许我们的执行一个异步的任务在后台。我们可以将耗时的操作放在异步任务当中来执行,并随时将任务执行的结果返回给我们的UI线程来更新我们的UI控件。通过AsyncTask我们可以轻松的解决多线程之间的通信问题。
4个步骤:当我们执行一个异步任务的时候,其需要按照下面的4个步骤分别执行
- onPreExecute(): 这个方法是在执行异步任务之前的时候执行,并且是在UI Thread当中执行的,通常我们在这个方法里做一些UI控件的初始化的操作,例如弹出要给ProgressDialog
- doInBackground(Params... params): 在onPreExecute()方法执行完之后,会马上执行这个方法,这个方法就是来处理异步任务的方法,Android操作系统会在后台的线程池当中开启一个worker thread来执行我们的这个方法,所以这个方法是在worker thread当中执行的,这个方法执行完之后就可以将我们的执行结果发送给我们的最后一个 onPostExecute 方法,在这个方法里,我们可以从网络当中获取数据等一些耗时的操作
- onProgressUpdate(Progess... values): 这个方法也是在UI Thread当中执行的,我们在异步任务执行的时候,有时候需要将执行的进度返回给我们的UI界面,例如下载一张网络图片,我们需要时刻显示其下载的进度,就可以使用这个方法来更新我们的进度。这个方法在调用之前,我们需要在 doInBackground 方法中调用一个 publishProgress(Progress) 的方法来将我们的进度时时刻刻传递给 onProgressUpdate 方法来更新
- onPostExecute(Result... result): 当我们的异步任务执行完之后,就会将结果返回给这个方法,这个方法也是在UI Thread当中调用的,我们可以将返回的结果显示在UI控件上
一个超简单的理解 AsyncTask 的例子:AsyncTask来从网络上加载一张图片
Activity代码:
1 private Button btn; 2 private ImageViewimageView; 3 privateProgressDialog progressDialog; 4 private final String IMGURL= "http://img0.pconline.com.cn/pconline/1206/18/2829090_3867bd63fd673471aa184c02_500.jpg"; 5 @Override 6 protected void onCreate(Bundle savedInstanceState) 7 { 8 super.onCreate(savedInstanceState); 9 setContentView(R.layout.asynctask_img); 10 btn=(Button)findViewById(R.id.buttonOnClicksAsyncTask); 11 imageView =(ImageView)findViewById(R.id.imageViewss); 12 progressDialog = newProgressDialog(this); 13 progressDialog.setTitle("提示信息"); 14 progressDialog.setMessage("正在下载中,请稍后......"); 15 progressDialog.setCancelable(false); 16 progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 17 btn.setOnClickListener(newView.OnClickListener() 18 { 19 @Override 20 public voidonClick(View v) 21 { 22 // 在UI Thread当中实例化AsyncTask对象,并调用execute方法 23 newMAsyncTask().execute(IMGURL); 24 } 25 }); 26 } 27 28 public class MAsyncTask extends AsyncTask<String, Integer, byte[]> 29 { 30 @Override 31 protected voidonPreExecute() 32 { 33 super.onPreExecute(); 34 progressDialog.show(); 35 } 36 @Override 37 protected byte[]doInBackground(String... params) 38 { 39 HttpClient httpClient = newDefaultHttpClient(); 40 HttpGet httpGet = newHttpGet(params[0]); 41 byte[] image =new byte[]{}; 42 try 43 { 44 HttpResponse httpResponse =httpClient.execute(httpGet); 45 HttpEntity httpEntity =httpResponse.getEntity(); 46 if(httpEntity!= null &&httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) 47 { 48 image = EntityUtils.toByteArray(httpEntity); 49 } 50 } 51 catch(Exception e) 52 { 53 e.printStackTrace(); 54 } 55 finally 56 { 57 httpClient.getConnectionManager().shutdown(); 58 } 59 return image; 60 } 61 @Override 62 protected voidonProgressUpdate(Integer... values) 63 { 64 super.onProgressUpdate(values); 65 } 66 @Override 67 protected voidonPostExecute(byte[] result) 68 { 69 super.onPostExecute(result); 70 // 将doInBackground方法返回的byte[]解码成要给Bitmap 71 Bitmap bitmap = BitmapFactory.decodeByteArray(result,0, result.length); 72 // 更新我们的ImageView控件 73 imageView.setImageBitmap(bitmap); 74 progressDialog.dismiss(); 75 } 76 } 77 }
一个ImageView控件和一个Button控件,当点击Button控件时,弹出一个ProgressDialog,然后开启一个异步任务,从网络中下载一张图片,并更新到我们的ImageView上。这里还要注意一点,如果我们要访问网络,必须还要给其授权才行
AndroidManifest.xml文件:
<uses-permission android:name="android.permission.INTERNET"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application>
效果图:
源码下载:
AndroidStudio下载: https://github.com/DickyQie/AsynTaskDemo.git