Android 台灣中文網
標題: 使用異步任務加載網絡上的圖片 [打印本頁]
作者: 暗桌之光 時間: 2011-8-2 13:18
標題: 使用異步任務加載網絡上的圖片
我們知道,如果要加載一個很耗時的操作,會阻塞主線程,這時我們可以想到開啟一個新的線程,避免阻塞,在android中也有這樣的問題,我們可以用異步任務來操作,異步任務也是開啟一個線程,線程裡面發一個訊息,然後通知去改變UI。
廢話不多說,我們先看一個例子:我們可以開啟這個網址:http://img1.3lian.com/img2011/07/20/05.jpg可以看到一副很好看的圖片,我們就要把這個圖片顯示出來,首先,還是先要佈局,我們要顯示一幅圖片,所以我們的佈局中需要一個ImageView,佈局很簡單,一個ImageView就可以了:- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <ImageView
- android:id="@+id/img"
- android:scaleType="fitXY"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
- </LinearLayout>
複製代碼 之後我們要寫一個Activity顯示這個圖片,不過要加載網絡上的圖片,我們需要從一個URL的流中獲取這個圖片,所以我們要寫一個方法來獲取這張圖片:- public Drawable loadImages(String url) {
- try {
- return Drawable.createFromStream((InputStream)(new URL(url)).openStream(), "test");
- }
- catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
複製代碼 從URL中開啟流,強制轉換成InputStream,然後從流中拿到Drawable。
既然可以獲取圖片了,我們要考慮一個問題,如果圖片很大,加載的很慢怎麼辦,我們豈不是要等很久?不要緊,這時候我們就可以用異步任務了。
首先我們要寫一個內部類,這個類部類是繼承自異步任務的,需要重載裡面的doBackGround方法:- private class ImageAsynTask extends AsyncTask<Void, Void, Drawable> {
-
- @Override
- protected Drawable doInBackground (Void... params) {
- String url = "http://img1.3lian.com/img2011/07/20/05.jpg";
- return loadImages(url);
- }
-
- @Override
- protected void onPostExecute (Drawable result) {
- super.onPostExecute(result);
- mDialog.dismiss();
- mImage.setImageDrawable(result);
- }
-
- @Override
- protected void onPreExecute () {
- super.onPreExecute();
- mDialog.show();
- }
- }
複製代碼 首先看這個方法:onPreExecute()這個方法是在doInBackGround前面執行。我們把這個方法寫出來,我們需要在獲取圖片之前等待的時間裡,寫一個progressDialog,顯示出來,提示用戶,目前正在加載圖片,需要等待一段時間。同時在後台操作doBackGround執行。
在doBackGround完成之後就會執行onPostExecute(Drawable result)方法,看這個方法就知道,必須在doBackGround完成之後,把得到的結果Drawable作為參數傳到onPostExecute方法裡面去,執行這個方法就表示已經加載完了,我們需要將progressDialog消失掉,然後把圖片顯示出來就可以了,整個過程很簡單。
看下整個Activity的代碼:- package com.test.asyntask;
-
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.URL;
-
- import android.app.Activity;
- import android.app.ProgressDialog;
- import android.graphics.drawable.Drawable;
- import android.os.AsyncTask;
- import android.os.Bundle;
- import android.widget.ImageView;
-
- import com.test.R;
-
- public class AsynTask extends Activity {
-
- private ImageView mImage;
- private ProgressDialog mDialog;
-
- @Override
- protected void onCreate (Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.asyn_task);
-
- mDialog = new ProgressDialog(this);
- mDialog.setTitle("請稍等");
- mDialog.setMessage("正在加載...");
-
- mImage = (ImageView) findViewById(R.id.img);
- new ImageAsynTask().execute();
- }
-
- private class ImageAsynTask extends AsyncTask<Void, Void, Drawable> {
-
- @Override
- protected Drawable doInBackground (Void... params) {
- String url = "http://img1.3lian.com/img2011/07/20/05.jpg";
- return loadImages(url);
- }
-
- @Override
- protected void onPostExecute (Drawable result) {
- super.onPostExecute(result);
- mDialog.dismiss();
- mImage.setImageDrawable(result);
- }
-
- @Override
- protected void onPreExecute () {
- super.onPreExecute();
- mDialog.show();
- }
- }
-
- @Override
- protected void onDestroy () {
- super.onDestroy();
- mDialog.dismiss();
- }
-
- public Drawable loadImages(String url) {
- try {
- return Drawable.createFromStream((InputStream)(new URL(url)).openStream(), "test");
- }
- catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
- }
複製代碼 執行一下,看下效果:
1.顯示progressDialog的時候,在加載圖片但是圖片還沒有加載出來的時候: