萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> 安卓開發 >> Android ListView異步加載圖片推薦

Android ListView異步加載圖片推薦

這是一篇關於Android ListView異步加載圖片的文章,下面是精品為您提供的一些內容,希望對您有所幫助

對於ListView,相信很多人都很熟悉,因為確實太常見了,所以,做的用戶體驗更好,就成了我們的追求。。。

常見的ListView中很少全是文字的,一般都是圖文共存的,而圖片的來源是服務器端(很少有寫在客戶端的吧。。。考慮客戶端的大小和更新的問題),所以,網絡問題就成了圖片是否能順利加載成功的決定性因素了。大家都知道每次啟動一個Android應用,都會啟動一個UI主線程,主要是響應用戶的交互,如果我們把不確定的獲取網絡圖片的操作放在UI主線程,結果也就不確定了。。。當然,如果你網絡足夠好的話,應該問題不大,但是,網絡誰能保證呢?所以就出現了“異步加載”的方法!

我先敘述一下異步加載的原理,說的通俗一點就是UI主線程繼續做與用戶交互的響應監聽和操作,而加載圖片的任務交到其他線程中去做,當圖片加載完成之後,再跟據某種機制(比如回調)繪制到要顯示的控件中。

首先,貼出AsyncBitmapLoader.java,這個類是關鍵,主要做的就是當加載圖片的時候,去緩沖區查找,如果有的話,則立刻返回Bitmap對象,省掉再去網絡服務器下載的時間和流量。

[java]

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.lang.ref.SoftReference;

import java.util.HashMap;

import onerain.ald.common.HttpUtils;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.os.Handler;

import android.os.Message;

import android.widget.ImageView;

/**

* @author oneRain

**/

public class AsyncBitmapLoader

{

/**

* 內存圖片軟引用緩沖

*/

private HashMap> imageCache = null;

public AsyncBitmapLoader()

{

imageCache = new HashMap>();

}

public Bitmap loadBitmap(final ImageView imageView, final String imageURL, final ImageCallBack imageCallBack)

{

//在內存緩存中,則返回Bitmap對象

if(imageCache.containsKey(imageURL))

{

SoftReference reference = imageCache.get(imageURL);

Bitmap bitmap = reference.get();

if(bitmap != null)

{

return bitmap;

}

}

else

{

/**

* 加上一個對本地緩存的查找

*/

String bitmapName = imageURL.substring(imageURL.lastIndexOf("/") + 1);

File cacheDir = new File("/mnt/sdcard/test/");

File[] cacheFiles = cacheDir.listFiles();

int i = 0;

for(; i

{

if(bitmapName.equals(cacheFiles[i].getName()))

{

break;

}

}

if(i < cacheFiles.length)

{

return BitmapFactory.decodeFile("/mnt/sdcard/test/" + bitmapName);

}

}

final Handler handler = new Handler()

{

/* (non-Javadoc)

* @see android.os.Handler#handleMessage(android.os.Message)

*/

@Override

public void handleMessage(Message msg)

{

// TODO Auto-generated method stub

imageCallBack.imageLoad(imageView, (Bitmap)msg.obj);

}

};

//如果不在內存緩存中,也不在本地(被jvm回收掉),則開啟線程下載圖片

new Thread()

{

/* (non-Javadoc)

* @see java.lang.Thread#run()

*/

@Override

public void run()

{

// TODO Auto-generated method stub

InputStream bitmapIs = HttpUtils.getStreamFromURL(imageURL);

Bitmap bitmap = BitmapFactory.decodeStream(bitmapIs);

imageCache.put(imageURL, new SoftReference(bitmap));

Message msg = handler.obtainMessage(0, bitmap);

handler.sendMessage(msg);

File dir = new File("/mnt/sdcard/test/");

if(!dir.exists())

{

dir.mkdirs();

}

File bitmapFile = new File("/mnt/sdcard/test/" +

imageURL.substring(imageURL.lastIndexOf("/") + 1));

if(!bitmapFile.exists())

{

try

{

bitmapFile.createNewFile();

}

catch (IOException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

}

FileOutputStream fos;

try

{

fos = new FileOutputStream(bitmapFile);

bitmap.compress(Bitmap.CompressFormat.JPEG,

100, fos);

fos.close();

}

catch (FileNotFoundException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

catch (IOException e)

{

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}.start();

return null;

}

/**

* 回調接口

* @author onerain

*

*/

public interface ImageCallBack

{

public void imageLoad(ImageView imageView, Bitmap bitmap);

}

}

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.lang.ref.SoftReference;

import java.util.HashMap;

import onerain.ald.common.HttpUtils;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.os.Handler;

import android.os.Message;

import android.widget.ImageView;

/**

* @author oneRain

**/

public class AsyncBitmapLoader

{

/**

* 內存圖片軟引用緩沖

*/

private HashMap> imageCache = null;

public AsyncBitmapLoader()

{

imageCache = new HashMap>();

}

public Bitmap loadBitmap(final ImageView imageView, final String imageURL, final ImageCallBack imageCallBack)

{

//在內存緩存中,則返回Bitmap對象

if(imageCache.containsKey(imageURL))

{

SoftReference reference = imageCache.get(imageURL);

Bitmap bitmap = reference.get();

if(bitmap != null)

{

return bitmap;

}

}

else

{

/**

* 加上一個對本地緩存的查找

*/

String bitmapName = imageURL.substring(imageURL.lastIndexOf("/") + 1);

File cacheDir = new File("/mnt/sdcard/test/");

File[] cacheFiles = cacheDir.listFiles();

int i = 0;

for(; i

{

if(bitmapName.equals(cacheFiles[i].getName()))

{

break;

}

}

if(i < cacheFiles.length)

{

return BitmapFactory.decodeFile("/mnt/sdcard/test/" + bitmapName);

}

}

final Handler handler = new Handler()

{

/* (non-Javadoc)

* @see android.os.Handler#handleMessage(android.os.Message)

*/

@Override

public void handleMessage(Message msg)

{

// TODO Auto-generated method stub

imageCallBack.imageLoad(imageView, (Bitmap)msg.obj);

}

};

//如果不在內存緩存中,也不在本地(被jvm回收掉),則開啟線程下載圖片

new Thread()

{

/* (non-Javadoc)

* @see java.lang.Thread#run()

*/

@Override

public void run()

{

// TODO Auto-generated method stub

InputStream bitmapIs = HttpUtils.getStreamFromURL(imageURL);

Bitmap bitmap = BitmapFactory.decodeStream(bitmapIs);

imageCache.put(imageURL, new SoftReference(bitmap));

Message msg = handler.obtainMessage(0, bitmap);

handler.sendMessage(msg);

File dir = new File("/mnt/sdcard/test/");

if(!dir.exists())

{

dir.mkdirs();

}

File bitmapFile = new File("/mnt/sdcard/test/" +

imageURL.substring(imageURL.lastIndexOf("/") + 1))

copyright © 萬盛學電腦網 all rights reserved