以前发过一篇有关加载图片的文章,是处理应用中常常遇到的加载列表缩略图与大图的文章,当时是因为赶项目,时间仓促,并没有过多的考虑,闲暇时间,反思了一下,觉得以前所用的方法过于笨拙且消耗手机资源加大,思量再三,又重新做了一个
此次引用了线程池ExecutorService与改用了Handler的post方法
采用线程池的目的:
1、大幅减少开启线程的数量,重复利用有限的线程
2、减少手机的资源损耗
采用Handler的Post方法的目的:
1、是为了更加规范的调用API
2、是图片的呈现更加可靠
不多说了!
-------------------------------------------------------------------------------------------------------------------------------
java代码 :
图片加载管理类AsynDownloadManager,需要从外部传入UI线程的Handler
public class AsynDownloadManager {
private static String ThumbFolder = "Temp/Thumb";//缩略图文件夹
private static String ImageFolder="Temp/Image";//大图文件夹
private static Handler handler;//UI handler
private static ExecutorService pool;//线程池
private static Map<String, SoftReference<Bitmap>> cacheImage;//软引用
private int ThreadCount=5;//默认线程池可用线程数
/**
* 创建目录
*/
static {
if (isSDCardAvailable()) {
File file = new File(Environment.getExternalStorageDirectory(),ThumbFolder);
if (!file.exists()) {
file.mkdirs();
}
File file1 = new File(Environment.getExternalStorageDirectory(),ImageFolder);
if (!file1.exists()) {
file1.mkdirs();
}
}
}
public AsynDownloadManager() {
cacheImage = new HashMap<String, SoftReference<Bitmap>>();
pool = Executors.newFixedThreadPool(ThreadCount);
}
static AsynDownloadManager manager=null;
//**********************************************************************************供外部调用的主方法
/**
* 获取加载器
* @return AsynDownloadManager
*/
public static AsynDownloadManager getInterface(){
if(manager==null){
manager=new AsynDownloadManager();
}
return manager;
}
/**
* 加载图片(缩略图)
* @param url
* @param imageView
*/
public static void loadThembBitmap(final String url, final ImageView imageView) {
pool.submit(new Runnable() {
public void run() {
//首先从SoftReference中获取
Bitmap bitmapTemp=getFromSoftReference(url);
if(bitmapTemp==null){
//从SDcard中获取
bitmapTemp=getFromSDcard(url, ThumbFolder,false);
if(bitmapTemp==null){
//从URL获取
bitmapTemp=getFromURL(url, ThumbFolder,false);
}
}
final Bitmap bitmap=bitmapTemp;
handler.post(new Runnable() {//发送到Handler队列,依次显示
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
});
}
/**
* 加载图片(大图)
* @param url
* @param imageView
* @param isZip 是否压缩
*/
public static void loadBitmap(final String url, final ImageView imageView,final boolean isZip){
pool.submit(new Runnable() {
public void run() {
//因为单图较大,不用SoftReference
Bitmap bitmapTemp=null;
//从SDcard中获取
bitmapTemp=getFromSDcard(url, ImageFolder,isZip);
if(bitmapTemp==null){
//从URL获取
bitmapTemp=getFromURL(url, ImageFolder,isZip);
}
final Bitmap bitmap=bitmapTemp;
handler.post(new Runnable() {//发送到Handler队列,依次显示
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
});
}
//**********************************************************************************
/**
* 从缓存中获取
* @param url
* @param bitmap
* @return Bitmap
*/
public static Bitmap getFromSoftReference(String url){
if(!cacheImage.containsKey(url)){
return null;
}else{
return cacheImage.get(url).get();
}
}
/**
* 从SDcard获取(下载并返回)
* @param imageUrl
* @param folderPath
* @return Bitmap
*/
public static Bitmap getFromURL(String imageUrl, String folderPath,boolean isZip){
URL mUrl;
InputStream is = null;
Bitmap bitmap = null;
try {
mUrl = new URL(imageUrl);
is = (InputStream) mUrl.getContent();
if(isSDCardAvailable()){
String fileName = imageUrl.substring(imageUrl.lastIndexOf('/')+1);
File basePathFile = new File(Environment.getExternalStorageDirectory(), folderPath);
File file = new File(basePathFile, fileName+".tmp");
if(!file.exists()){
file.createNewFile();
}
FileOutputStream outputStream = new FileOutputStream(file);
byte[] b = new byte[512];
int offset;
while((offset=is.read(b))!=-1){
outputStream.write(b, 0, offset);
}
outputStream.flush();
outputStream.close();
is.close();
basePathFile = new File(basePathFile, fileName);
if(basePathFile.exists()){
basePathFile.delete();
}
if(file.renameTo(basePathFile)){
is = new FileInputStream(basePathFile);
}
// 读取图片
bitmap=getBitmap(basePathFile.getAbsolutePath(), isZip);
if(isZip==false){
//缩略图加入到软引用
SoftReference<Bitmap> softReference=new SoftReference<Bitmap>(bitmap);
cacheImage.put(imageUrl, softReference);
}
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return bitmap;
}
/**
* 从SDcard获取
* @param url
* @param folderPath
* @return Bitmap
*/
public static Bitmap getFromSDcard(String url,String folderPath,boolean isZip){
Bitmap bitmap = null;
String fileName = url.substring(url.lastIndexOf('/')+1);
File basePathFile = new File(Environment.getExternalStorageDirectory(), folderPath);
basePathFile = new File(basePathFile, fileName);
if(basePathFile.exists()){
bitmap=getBitmap(basePathFile.getAbsolutePath(), isZip);
}
return bitmap;
}
/**
* 检查SDCard是否可用
*
* @return
*/
public static final boolean isSDCardAvailable() {
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
}
//---------------------------------------------------------------------------------
/**
* 读取SDcard中的图片资源(解决内存溢出问题)
* @param pathName 文件路径名
* @param isZip 是否降低采样率
* @return Bitmap
*/
public static Bitmap getBitmap(String pathName,boolean isZip){
Bitmap bitmap=null;
if(isZip==true){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;//图片宽高都为原来的二分之一,即图片为原来的四分之一
bitmap=BitmapFactory.decodeFile(pathName, options);
}else{
bitmap=BitmapFactory.decodeFile(pathName);
}
return bitmap;
}
//---------------------------------------------------------------便于外部修改参数
public static String getThumbFolder() {
return ThumbFolder;
}
public static void setThumbFolder(String thumbFolder) {
ThumbFolder = thumbFolder;
}
public static String getImageFolder() {
return ImageFolder;
}
public static void setImageFolder(String imageFolder) {
ImageFolder = imageFolder;
}
public int getThreadCount() {
return ThreadCount;
}
public void setThreadCount(int threadCount) {
ThreadCount = threadCount;
}
public Handler getHandler() {
return handler;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
}
------------------------------------------------------------------------------------------------------------------------------
调用示例 :
一、对于缩略图:
1、在Activity中实例化AsynDownloadManager:
Handler handler=new Handler();
2、对于ListView或GridView中的缩略图,一般可在自定义Adapter的的构造中:
AsynDownloadManager manager=AsynDownloadManager.getInterface();
manager.setHandler(handler);
getView()方法中作如下调用:
manager.loadThembBitmap(urlList.get(position), imageView);
3、OK
二、对于大图:(压缩)
前两步同上
3、 直接调用
AsynDownloadManager.getInterface().loadBitmap(url, ImageView, true);
当然最后那个参数也可以用false,即不压缩的模式
---------------------------------------------------------------------------------------------------------------------------------
OK!
此次引用了线程池ExecutorService与改用了Handler的post方法
采用线程池的目的:
1、大幅减少开启线程的数量,重复利用有限的线程
2、减少手机的资源损耗
采用Handler的Post方法的目的:
1、是为了更加规范的调用API
2、是图片的呈现更加可靠
![device-2013-04-07-143747.png device-2013-04-07-143747.png](http://www.eoeandroid.com/data/attachment/forum/201304/07/143825u49d94na4zipwwtz.png)
不多说了!
-------------------------------------------------------------------------------------------------------------------------------
java代码 :
图片加载管理类AsynDownloadManager,需要从外部传入UI线程的Handler
public class AsynDownloadManager {
private static String ThumbFolder = "Temp/Thumb";//缩略图文件夹
private static String ImageFolder="Temp/Image";//大图文件夹
private static Handler handler;//UI handler
private static ExecutorService pool;//线程池
private static Map<String, SoftReference<Bitmap>> cacheImage;//软引用
private int ThreadCount=5;//默认线程池可用线程数
/**
* 创建目录
*/
static {
if (isSDCardAvailable()) {
File file = new File(Environment.getExternalStorageDirectory(),ThumbFolder);
if (!file.exists()) {
file.mkdirs();
}
File file1 = new File(Environment.getExternalStorageDirectory(),ImageFolder);
if (!file1.exists()) {
file1.mkdirs();
}
}
}
public AsynDownloadManager() {
cacheImage = new HashMap<String, SoftReference<Bitmap>>();
pool = Executors.newFixedThreadPool(ThreadCount);
}
static AsynDownloadManager manager=null;
//**********************************************************************************供外部调用的主方法
/**
* 获取加载器
* @return AsynDownloadManager
*/
public static AsynDownloadManager getInterface(){
if(manager==null){
manager=new AsynDownloadManager();
}
return manager;
}
/**
* 加载图片(缩略图)
* @param url
* @param imageView
*/
public static void loadThembBitmap(final String url, final ImageView imageView) {
pool.submit(new Runnable() {
public void run() {
//首先从SoftReference中获取
Bitmap bitmapTemp=getFromSoftReference(url);
if(bitmapTemp==null){
//从SDcard中获取
bitmapTemp=getFromSDcard(url, ThumbFolder,false);
if(bitmapTemp==null){
//从URL获取
bitmapTemp=getFromURL(url, ThumbFolder,false);
}
}
final Bitmap bitmap=bitmapTemp;
handler.post(new Runnable() {//发送到Handler队列,依次显示
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
});
}
/**
* 加载图片(大图)
* @param url
* @param imageView
* @param isZip 是否压缩
*/
public static void loadBitmap(final String url, final ImageView imageView,final boolean isZip){
pool.submit(new Runnable() {
public void run() {
//因为单图较大,不用SoftReference
Bitmap bitmapTemp=null;
//从SDcard中获取
bitmapTemp=getFromSDcard(url, ImageFolder,isZip);
if(bitmapTemp==null){
//从URL获取
bitmapTemp=getFromURL(url, ImageFolder,isZip);
}
final Bitmap bitmap=bitmapTemp;
handler.post(new Runnable() {//发送到Handler队列,依次显示
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
});
}
//**********************************************************************************
/**
* 从缓存中获取
* @param url
* @param bitmap
* @return Bitmap
*/
public static Bitmap getFromSoftReference(String url){
if(!cacheImage.containsKey(url)){
return null;
}else{
return cacheImage.get(url).get();
}
}
/**
* 从SDcard获取(下载并返回)
* @param imageUrl
* @param folderPath
* @return Bitmap
*/
public static Bitmap getFromURL(String imageUrl, String folderPath,boolean isZip){
URL mUrl;
InputStream is = null;
Bitmap bitmap = null;
try {
mUrl = new URL(imageUrl);
is = (InputStream) mUrl.getContent();
if(isSDCardAvailable()){
String fileName = imageUrl.substring(imageUrl.lastIndexOf('/')+1);
File basePathFile = new File(Environment.getExternalStorageDirectory(), folderPath);
File file = new File(basePathFile, fileName+".tmp");
if(!file.exists()){
file.createNewFile();
}
FileOutputStream outputStream = new FileOutputStream(file);
byte[] b = new byte[512];
int offset;
while((offset=is.read(b))!=-1){
outputStream.write(b, 0, offset);
}
outputStream.flush();
outputStream.close();
is.close();
basePathFile = new File(basePathFile, fileName);
if(basePathFile.exists()){
basePathFile.delete();
}
if(file.renameTo(basePathFile)){
is = new FileInputStream(basePathFile);
}
// 读取图片
bitmap=getBitmap(basePathFile.getAbsolutePath(), isZip);
if(isZip==false){
//缩略图加入到软引用
SoftReference<Bitmap> softReference=new SoftReference<Bitmap>(bitmap);
cacheImage.put(imageUrl, softReference);
}
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return bitmap;
}
/**
* 从SDcard获取
* @param url
* @param folderPath
* @return Bitmap
*/
public static Bitmap getFromSDcard(String url,String folderPath,boolean isZip){
Bitmap bitmap = null;
String fileName = url.substring(url.lastIndexOf('/')+1);
File basePathFile = new File(Environment.getExternalStorageDirectory(), folderPath);
basePathFile = new File(basePathFile, fileName);
if(basePathFile.exists()){
bitmap=getBitmap(basePathFile.getAbsolutePath(), isZip);
}
return bitmap;
}
/**
* 检查SDCard是否可用
*
* @return
*/
public static final boolean isSDCardAvailable() {
return Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED);
}
//---------------------------------------------------------------------------------
/**
* 读取SDcard中的图片资源(解决内存溢出问题)
* @param pathName 文件路径名
* @param isZip 是否降低采样率
* @return Bitmap
*/
public static Bitmap getBitmap(String pathName,boolean isZip){
Bitmap bitmap=null;
if(isZip==true){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;//图片宽高都为原来的二分之一,即图片为原来的四分之一
bitmap=BitmapFactory.decodeFile(pathName, options);
}else{
bitmap=BitmapFactory.decodeFile(pathName);
}
return bitmap;
}
//---------------------------------------------------------------便于外部修改参数
public static String getThumbFolder() {
return ThumbFolder;
}
public static void setThumbFolder(String thumbFolder) {
ThumbFolder = thumbFolder;
}
public static String getImageFolder() {
return ImageFolder;
}
public static void setImageFolder(String imageFolder) {
ImageFolder = imageFolder;
}
public int getThreadCount() {
return ThreadCount;
}
public void setThreadCount(int threadCount) {
ThreadCount = threadCount;
}
public Handler getHandler() {
return handler;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
}
------------------------------------------------------------------------------------------------------------------------------
调用示例 :
一、对于缩略图:
1、在Activity中实例化AsynDownloadManager:
Handler handler=new Handler();
2、对于ListView或GridView中的缩略图,一般可在自定义Adapter的的构造中:
AsynDownloadManager manager=AsynDownloadManager.getInterface();
manager.setHandler(handler);
getView()方法中作如下调用:
manager.loadThembBitmap(urlList.get(position), imageView);
3、OK
二、对于大图:(压缩)
前两步同上
3、 直接调用
AsynDownloadManager.getInterface().loadBitmap(url, ImageView, true);
当然最后那个参数也可以用false,即不压缩的模式
---------------------------------------------------------------------------------------------------------------------------------
OK!