Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> android:異步任務asyncTask介紹及異步任務下載圖片(帶進度條)

android:異步任務asyncTask介紹及異步任務下載圖片(帶進度條)

編輯:關於android開發

android:異步任務asyncTask介紹及異步任務下載圖片(帶進度條)


為什麼要用異步任務?

在android中只有在主線程才能對ui進行更新操作,而其它線程不能直接對ui進行操作

android本身是一個多線程的操作系統,我們不能把所有的操作都放在主線程中操作 ,比如一些耗時操作。如果放在主線程中 會造成阻塞 而當阻塞事件過長時 系統會拋出anr異常。所以我們要使用異步任務。android為我們提供了一個封裝好的組件asynctask。

AsyncTask可以在子線程中更新ui,封裝簡化了異步操作。適用於簡單的異步處理。如果多個後台任務時就要使用Handler了 在這裡就不再說明。

AsyncTask通常用於被繼承。AsyncTask定義了三種泛型類型

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">

    </imageview></framelayout></button></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{
		
		//執行異步任務(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"></uses-permission>

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved