Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android AsyncTask使用

android AsyncTask使用

編輯:關於Android編程

 

 

異步任務 AsyncTask使用

 

android中實現異步機制主要有Thread加Handler和AsyncTask,今天主要記錄一下AsyncTask的學習過程,以備以後之需。

 

一、構建AsyncTask子類的參數

AsyncTask是一個抽象類。通常用於被繼承,繼承AsyncTask需要指定如下三個泛型參數。

 

Params: 啟動任務時輸入參數的類型。Progress:後台任務執行過程中進度之的類型。Result: 後台執行任務完成後返回結果的類型。
二、實現AsyncTask需要重寫的方法 當一個異步任務執行的時候一般需要實現一下4個方法: onPreExcute:通常是用戶完成一些UI的初始化操作,譬如加載進度條等。doInBackground(Params...):當調用完onPreExcute()後立即執行這個方法,主要是後台進行一些耗時的操作,在這方法中可以調用publishProgress(Progress...)來顯示任務已經執行的進度。onProgressUpdate(Progress...):在doInBackground()方法中調用publicProgress方法會觸發該方法的執行,用於UI組件顯示任務實時執行的進度。onPostExcute():當後台任務完成後會調用此方法,後台執行任務返回的結果作為參數傳遞給這個方法,顯示更新在UI主線程中。 三、調用規則

 

  Threading rules
  There are a few threading rules that must be followed for this class to work properly:

  1、The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
  2、The task instance must be created on the UI thread.
  3、execute(Params...) must be invoked on the UI thread.
  4、Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
  5、The task can be executed only once (an exception will be thrown if a second execution is attempted.)

 

大概意思就是說:

 

必須在UI主線程中創建AsyncTask的實例。excute()方法必須在UI主線程中調用。不需要手動調用onPreExcute、doInBackground、onProgressUpdate、onPostExcute四個方法。一個AsyncTask實例只能執行一個任務。 四、實例Demo 我們先看一下效果,然後再來講解一下具體的實現過程。本次demo主要實現的是異步加載一張網絡圖片,並在加載過程中顯示加載的進度百分比,主要涉及到一些IO操作以及網絡請求等知識點。

 

\ \ \

圖1 圖2 圖3

 

圖1顯示的是功能,主要是點擊button後進入加載網絡圖片頁面;

圖2顯示的是加載網絡圖片過程中的進度百分比;

圖3顯示的是當加載進度百分比為100%時,顯示要加載的網絡圖片。

 

下面我們來分析一下具體的實現代碼:

主界面的布局就不貼了,主要就是一個button按鈕,然後在MainActivity中實現頁面跳轉,我們主要來看看ImageTest.class 中是如何實現加載網絡圖片的。

首先是xml布局,布局很簡單,一個ImageView組件顯示網絡圖片,一個ProgressBar組件用於顯示進度,一個TextView用於顯示加載的進度百分比,總得布局用RelativeLayout實現。

 




    

    
    
    


然後是ImageTest.class,在這裡面主要是加載網絡圖片的主題代碼。代碼中注釋寫的都一清二楚,直接上代碼了。

 

 

package com.example.asynctaskdemo;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.nfc.Tag;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

/**
 * 顯示一張網絡圖片
 * 
 * @author crazyandcoder
 * @date [2015-8-9 下午4:11:27]
 */
public class ImageTest extends Activity {

	private String TAG = ImageTest.class;
	private ImageView mImageView;
	private ProgressBar mProgressBar;
	private TextView mTextProgress;

	private MyAsyncTaskShowImg mTask;
	private static String mImgUrl = http://h.hiphotos.baidu.com/image/pic/item/9922720e0cf3d7ca14dcc750f71fbe096b63a9ea.jpg;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.image);
		initView();

		mTask = new MyAsyncTaskShowImg();
		mTask.execute(mImgUrl);
	}

	private void initView() {
		mTextProgress = (TextView) findViewById(R.id.mTextprogress);
		mImageView = (ImageView) findViewById(R.id.imageView1);
		mProgressBar = (ProgressBar) findViewById(R.id.progress);

	}

	class MyAsyncTaskShowImg extends AsyncTask {

		/**
		 * 初始化UI控件
		 * 
		 * @see android.os.AsyncTask#onPreExecute()
		 */
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			mProgressBar.setVisibility(View.VISIBLE);
			mTextProgress.setText(0%);
		}

		/**
		 * 執行復雜的耗時任務
		 * 
		 * @param params
		 * @return
		 * @see android.os.AsyncTask#doInBackground(Params[])
		 */
		@Override
		protected Bitmap doInBackground(String... params) {

			// 網絡中圖片的地址
			String mImgUrl = params[0];

			String mFileName = temp_pic;
			Log.d(TAG, mImgUrl  is  + mImgUrl);
			// 網絡中圖片最終將轉化為bitmap類型返回給imageview顯示
			Bitmap mBitmap = null;

			// 獲取數據的輸入流
			InputStream is = null;
			OutputStream out = null;
			HttpURLConnection connection;

			try {

				// 將網絡圖片地址以流的方式轉化為bitmap類型
				connection = (HttpURLConnection) new URL(mImgUrl).openConnection();
				connection.setDoInput(true);
				connection.setDoOutput(false);

				// 設置鏈接超時時間
				connection.setConnectTimeout(10 * 1000);
				is = connection.getInputStream();
				out = openFileOutput(mFileName, MODE_PRIVATE);
				byte[] data = new byte[1024];
				// 每次讀到的長度
				int seg = 0;
				// 總得數據大小
				long totalSize = connection.getContentLength();
				Log.d(TAG, total size is  + totalSize);
				// 現在的進度
				long current = 0;
				//
				while (!(mTask.isCancelled()) && (seg = is.read(data)) != -1) {
					// 當前總的進度
					current += seg;
					Log.d(TAG, current size is  + current);
					// 下載百分比
					int progress = (int) ((float) current / totalSize * 100);

					Log.d(TAG, progress size is  + progress);
					// 通知更新進度
					publishProgress(progress);
					out.write(data, 0, seg);
				}

				mBitmap = BitmapFactory.decodeFile(getFileStreamPath(mFileName).getAbsolutePath());
				Log.d(TAG, file is  + getFileStreamPath(mFileName).getAbsolutePath());
				connection.disconnect();
				is.close();
				out.close();

			} catch (MalformedURLException e) {
				e.printStackTrace();

			} catch (IOException e) {
				e.printStackTrace();

			}

			return mBitmap;
		}

		/**
		 * 顯示從網絡中加載圖片的進度
		 * 
		 * @param values
		 * @see android.os.AsyncTask#onProgressUpdate(Progress[])
		 */
		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			mTextProgress.setText(values[0] + %);
		}

		/**
		 * 將doInBackground中執行的結果返回給該方法,用於更新UI控件
		 * 
		 * @param result
		 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
		 */
		@Override
		protected void onPostExecute(Bitmap result) {
			super.onPostExecute(result);
			mProgressBar.setVisibility(View.GONE);
			 mTextProgress.setVisibility(View.GONE);
			mImageView.setImageBitmap(result);
			Toast.makeText(ImageTest.this, 圖片加載完成., Toast.LENGTH_LONG).show();

		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		if (mTask != null && mTask.getStatus() == AsyncTask.Status.RUNNING) {
			//cancel方法只是將AsyncTask對應的狀態標記為cancel狀態,不是真的取消
			mTask.cancel(true);
		}
	}

}

代碼很簡單,看看注釋就應該明白了。

 

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