AsyncTask方便我們在子線程進行耗時操作,並且方便切換到UI線程進行更新UI,不需要再使用Handler等在子線程與主線程之間進行通信了。
AsyncTask的基本用法
AsyncTask是一個抽象類,因此使用它就要寫一個類繼承它,繼承的時候需要指定三個泛型參數
- Params
在執行後臺任務時需要傳入的參數類型,doInbackground()方法的參數 - Progress
如果需要在界面上顯示執行的任務進度,則使用這裏指定的泛型指定的類型作爲進度單位,onProgressUpdate()方法和publishProgress()方法的參數 - Return
任務執行完成後,如果需要返回值,就使用這裏指定的泛型作爲返回值的類型,doInbackground()方法的返回類型以及onPostExecute()方法的參數
重寫他的幾個方法,一個簡單的AsyncTask就可以寫成
class MyAsyncTask extends AsyncTask<Void, Integer, Boolean>{
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected Boolean doInBackground(Void... params) {
// TODO Auto-generated method stub
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
重寫的這四個方法爲
- onPreExecute()
這個方法會在任務開始前進行調用,在這裏可以執行一些準備工作,例如顯示一個進度條等。 - doInbackground(Void…params)
執行任務的方法,這個方法是在子線程中執行的,因此可以執行一些耗時任務,執行完畢後需要用return語句進行返回,返回的類型就是繼承AsyncTask時定義的第三個參數,如果定義爲Void,則不需要返回,定義爲Integer,就返回Integer類型。注意,由於該方法是在子線程中執行的,因此不可以更新UI,如果需要更新UI,應該調用publishProgress(Progress…)方法完成。 - onProgressUpdate(Integer…values)
當後臺任務中調用了publishProgress(Progress…)方法後,這個方法很快便會被調用,方法中的參數就是publishProgress(Progress)方法傳遞進來的參數,該方法可以利用傳遞進來的參數更新UI,例如更新進度條的進度。 - onPostExecute(Boolean…result)
當後臺任務執行完畢,通過return語句進行返回後,該方法馬上會被調用,返回的結果作爲參數傳遞到該方法中。在該方法中可以進行UI操作,例如提示任務完成,關閉進度條等。
使用實例(後臺下載圖片,並顯示)
繼承AsyncTask,泛型分別爲URL,Integer,Boolean,說明下載任務需要傳遞一個URL參數,然後更新進度是Integer類型,返回結果是Boolean類型
class DownloadAsyncTask extends AsyncTask<URL, Integer, Boolean>
重寫onPreExecute方法
在這裏,定義了一個進度條,顯示在主界面
@Override
//運行前的準備
protected void onPreExecute() {
dialog=new ProgressDialog(MainActivity.this);
dialog.setTitle("下載進度");
dialog.setMax(100);
dialog.setCancelable(true);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.show();
}
重寫doInbackground方法
傳遞進來需要下載的Url地址,然後通過HttpURLConnection訪問網絡,通過IO流進行下載圖片,然後計算進度,由於圖片太小,下載的太快,所以我在這裏每讀取一次byte[1024],就使線程休眠100毫秒,沒讀取一次就計算一次進度,然後publishProgress方法通知更新進度條
@Override
protected Boolean doInBackground(URL... params) {
HttpURLConnection connection=null;
int contentLenth=0;
try {
connection=(HttpURLConnection) params[0].openConnection();
connection.setConnectTimeout(4000);
connection.setReadTimeout(4000);
connection.setRequestMethod("GET");
contentLenth=connection.getContentLength();
File file=new File(getCacheDir()+"xu.jpg");
InputStream in=connection.getInputStream();
FileOutputStream out=new FileOutputStream(file);
byte[] b=new byte[1024];
int len=0;
int totalSize=0;
while((len=in.read(b))!=-1){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.write(b, 0, len);
totalSize+=len*100;
int progress=(totalSize/contentLenth);
publishProgress(progress);
}
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
重寫onProgressUpdate方法
通過publishProgress方法傳遞進來的進度更新進度條的進度。
@Override
protected void onProgressUpdate(Integer... values) {
dialog.setProgress(values[0]);
}
重寫onPostExecute方法
如果返回的是true,就顯示下載成功,並將圖片顯示出來通過BitmapFactory.decodeStream(file)方法得到一個Bitmap對象,然後顯示在ImageView中。
@Override
protected void onPostExecute(Boolean result) {
dialog.dismiss();
if(result){
Toast.makeText(MainActivity.this, "下載成功", Toast.LENGTH_LONG).show();
File file=new File(getCacheDir()+"xu.jpg");
Bitmap bitmap=null;
try {
bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
mShowImageView.setImageBitmap(bitmap);
}else{
Toast.makeText(MainActivity.this, "下載失敗", Toast.LENGTH_LONG).show();
}
}
調用執行
界面一打開,就開始下載,然後完成後在ImageView上顯示
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mShowImageView=(ImageView) findViewById(R.id.main_show_ImageView);
try {
new DownloadAsyncTask().execute(new URL("https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1465108635&di=d36b371b3eeb89bf304ccfbee2b4f1cd&src=http://picture.youth.cn/dmzb/201305/W020130514542662922703.jpg"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}