android:異步任務asyncTask介紹及異步任務下載圖片(帶進度條)
來自: http://blog.csdn.net/su20145104009/article/details/50759618
為什么要用異步任務?
在android中只有在主線程才能對ui進行更新操作,而其它線程不能直接對ui進行操作
android本身是一個多線程的操作系統,我們不能把所有的操作都放在主線程中操作 ,比如一些耗時操作。如果放在主線程中 會造成阻塞 而當阻塞事件過長時 系統會拋出anr異常。所以我們要使用異步任務。android為我們提供了一個封裝好的組件asynctask。
AsyncTask可以在子線程中更新ui,封裝簡化了異步操作。適用于簡單的異步處理。如果多個后臺任務時就要使用Handler了 在這里就不再說明。
AsyncTask通常用于被繼承。AsyncTask定義了三種泛型類型<Params,Progress,Result>
Params:啟動任務時輸入的參數類型
Progress:后臺任務執行的百分比
Result:執行任務完成后返回結果的類型
繼承AsyncTask后要重寫的方法有:
doInBackgroud:必須重寫,異步執行后臺線程要完成的任務,耗時任務要寫在這里,并且在這里不能操作ui。可以調用 publishProgress方法來更新實時的任務進度
onPreExecute:執行耗時操作前調用,可以完成一些初始化操作
onPostExecute:在doInBackground 執行完成后,主線程調用此方法,可以在此方法中操作ui
onProgressUpdate:在doInBackgroud方法中調用publishProgress方法,更新任務的執行進度后 就會調用這個方法
下面通過一個實例來了解AsyncTask
首先附上運行結果

布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn_download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="點擊下載" />
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<ImageView
android:id="@+id/iv_image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitCenter" />
</FrameLayout>
</LinearLayout>MainActivity
package com.example.asynctask;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URLConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity implements OnClickListener{
private ImageView image;
private ProgressDialog progress;
private Button btn_download;
private static String URL="http://img4.imgtn.bdimg.com/it/u=1256159061,743487979&fm=21&gp=0.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image=(ImageView) findViewById(R.id.iv_image);
btn_download=(Button) findViewById(R.id.btn_download);
progress=new ProgressDialog(this);
progress.setIcon(R.drawable.ic_launcher);
progress.setTitle("提示信息");
progress.setMessage("正在下載,請稍候...");
progress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
btn_download.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new MyAsyncTask().execute(URL);
}
/*
* String*********對應我們的URL類型
* Integer********進度條的進度值
* BitMap*********異步任務完成后返回的類型
* */
class MyAsyncTask extends AsyncTask<String, Integer, Bitmap>{
//執行異步任務(doInBackground)之前執行,并且在ui線程中執行
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
if(image!=null){
image.setVisibility(View.GONE);
}
//開始下載 對話框進度條顯示
progress.show();
progress.setProgress(0);
}
@Override
protected Bitmap doInBackground(String... params) {
// TODO Auto-generated method stub
//params是一個可變長的數組 在這里我們只傳進來了一個url
String url=params[0];
Bitmap bitmap=null;
URLConnection connection;
InputStream is;//用于獲取數據的輸入流
ByteArrayOutputStream bos;//可以捕獲內存緩沖區的數據,轉換成字節數組。
int len;
float count=0,total;//count為圖片已經下載的大小 total為總大小
try {
//獲取網絡連接對象
connection=(URLConnection) new java.net.URL(url).openConnection();
//獲取當前頁面的總長度
total=(int)connection.getContentLength();
//獲取輸入流
is=connection.getInputStream();
bos=new ByteArrayOutputStream();
byte []data=new byte[1024];
while((len=is.read(data))!=-1){
count+=len;
bos.write(data,0,len);
//調用publishProgress公布進度,最后onProgressUpdate方法將被執行
publishProgress((int)(count/total*100));
//為了顯示出進度 人為休眠0.5秒
Thread.sleep(500);
}
bitmap=BitmapFactory.decodeByteArray(bos.toByteArray(), 0, bos.toByteArray().length);
is.close();
bos.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bitmap;
}
//在ui線程中執行 可以操作ui
@Override
protected void onPostExecute(Bitmap bitmap) {
// TODO Auto-generated method stub
super.onPostExecute(bitmap);
//下載完成 對話框進度條隱藏
progress.cancel();
image.setImageBitmap(bitmap);
image.setVisibility(View.VISIBLE);
}
/*
* 在doInBackground方法中已經調用publishProgress方法 更新任務的執行進度后
* 調用這個方法 實現進度條的更新
* */
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
progress.setProgress(values[0]);
}
}
} 最后不要忘記在AndroidManifest文件中配置網絡訪問權限
<uses-permission android:name="android.permission.INTERNET"/>
本文由用戶 WarnerOBrie 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!