java加载网图并缓存下来_android下载网络图片并缓存

本文介绍了一个Android应用中实现异步下载网络图片并缓存到内存或外部文件的方案,包括AsyncImageLoader类和LoaderImpl类的详细实现,用于高效管理和加载图片。
摘要由CSDN通过智能技术生成

异步下载网络图片,并提供是否缓存至内存或外部文件的功能

异步加载类AsyncImageLoader

public void downloadImage(final String url, final ImageCallback callback);

public void downloadImage(final String url, final boolean cache2Memory, final ImageCallback callback);

public void setCache2File(boolean flag);

public void setCachedDir(String dir);

图片下载和缓存实现类LoaderImpl

1.AsyncImageLoader.java

package com.imagecache;

import java.lang.ref.SoftReference;

import java.util.HashMap;

import java.util.HashSet;

import java.util.Map;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import android.content.Context;

import android.graphics.Bitmap;

import android.os.Handler;

import android.util.Log;

public class AsyncImageLoader {

//保存正在下载的图片URL集合,避免重复下载用

private static HashSet sDownloadingSet;

//软引用内存缓存

private static Map> sImageCache;

//图片三种获取方式管理者,网络URL获取、内存缓存获取、外部文件缓存获取

private static LoaderImpl impl;

//线程池相关

private static ExecutorService sExecutorService;

//通知UI线程图片获取ok时使用

private Handler handler;

/**

* 异步加载图片完毕的回调接口

*/

public interface ImageCallback{

/**

* 回调函数

* @param bitmap: may be null!

* @param imageUrl

*/

public void onImageLoaded(Bitmap bitmap, String imageUrl);

}

static{

sDownloadingSet = new HashSet();

sImageCache = new HashMap>();

impl = new LoaderImpl(sImageCache);

}

public AsyncImageLoader(Context context){

handler = new Handler();

startThreadPoolIfNecessary();

String defaultDir = context.getCacheDir().getAbsolutePath();

setCachedDir(defaultDir);

}

/**

* 是否缓存图片至/data/data/package/cache/目录

* 默认不缓存

*/

public void setCache2File(boolean flag){

impl.setCache2File(flag);

}

/**

* 设置缓存路径,setCache2File(true)时有效

*/

public void setCachedDir(String dir){

impl.setCachedDir(dir);

}

/**开启线程池*/

public static void startThreadPoolIfNecessary(){

if(sExecutorService == null || sExecutorService.isShutdown() || sExecutorService.isTerminated()){

sExecutorService = Executors.newFixedThreadPool(3);

//sExecutorService = Executors.newSingleThreadExecutor();

}

}

/**

* 异步下载图片,并缓存到memory中

* @param url

* @param callback  see ImageCallback interface

*/

public void downloadImage(final String url, final ImageCallback callback){

downloadImage(url, true, callback);

}

/**

*

* @param url

* @param cache2Memory 是否缓存至memory中

* @param callback

*/

public void downloadImage(final String url, final boolean cache2Memory, final ImageCallback callback){

if(sDownloadingSet.contains(url)){

Log.i("AsyncImageLoader", "###该图片正在下载,不能重复下载!");

return;

}

Bitmap bitmap = impl.getBitmapFromMemory(url);

if(bitmap != null){

if(callback != null){

callback.onImageLoaded(bitmap, url);

}

}else{

//从网络端下载图片

sDownloadingSet.add(url);

sExecutorService.submit(new Runnable(){

@Override

public void run() {

final Bitmap bitmap = impl.getBitmapFromUrl(url, cache2Memory);

handler.post(new Runnable(){

@Override

public void run(){

if(callback != null)

callback.onImageLoaded(bitmap, url);

sDownloadingSet.remove(url);

}

});

}

});

}

}

/**

* 预加载下一张图片,缓存至memory中

* @param url

*/

public void preLoadNextImage(final String url){

//将callback置为空,只将bitmap缓存到memory即可。

downloadImage(url, null);

}

}

2.LoaderImpl.java

package com.imagecache;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.UnsupportedEncodingException;

import java.lang.ref.SoftReference;

import java.net.HttpURLConnection;

import java.net.URL;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.util.Map;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

/**

*

* @author Administrator

* @desc 异步加载图片管理器

*

*/

public class LoaderImpl {

//内存中的软应用缓存

private Map> imageCache;

//是否缓存图片至本地文件

private boolean cache2FileFlag = false;

//缓存目录,默认是/data/data/package/cache/目录

private String cachedDir;

public LoaderImpl(Map> imageCache){

this.imageCache = imageCache;

}

/**

* 是否缓存图片至外部文件

* @param flag

*/

public void setCache2File(boolean flag){

cache2FileFlag = flag;

}

/**

* 设置缓存图片到外部文件的路径

* @param cacheDir

*/

public void setCachedDir(String cacheDir){

this.cachedDir = cacheDir;

}

/**

* 从网络端下载图片

* @param url 网络图片的URL地址

* @param cache2Memory 是否缓存(缓存在内存中)

* @return bitmap 图片bitmap结构

*

*/

public Bitmap getBitmapFromUrl(String url, boolean cache2Memory){

Bitmap bitmap = null;

try{

URL u = new URL(url);

HttpURLConnection conn = (HttpURLConnection)u.openConnection();

InputStream is = conn.getInputStream();

bitmap = BitmapFactory.decodeStream(is);

if(cache2Memory){

//1.缓存bitmap至内存软引用中

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

if(cache2FileFlag){

//2.缓存bitmap至/data/data/packageName/cache/文件夹中

String fileName = getMD5Str(url);

String filePath = this.cachedDir + "/" +fileName;

FileOutputStream fos = new FileOutputStream(filePath);

bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);

}

}

is.close();

conn.disconnect();

return bitmap;

}catch(IOException e){

e.printStackTrace();

return null;

}

}

/**

* 从内存缓存中获取bitmap

* @param url

* @return bitmap or null.

*/

public Bitmap getBitmapFromMemory(String url){

Bitmap bitmap = null;

if(imageCache.containsKey(url)){

synchronized(imageCache){

SoftReference bitmapRef = imageCache.get(url);

if(bitmapRef != null){

bitmap = bitmapRef.get();

return bitmap;

}

}

}

//从外部缓存文件读取

if(cache2FileFlag){

bitmap = getBitmapFromFile(url);

if(bitmap != null)

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

}

return bitmap;

}

/**

* 从外部文件缓存中获取bitmap

* @param url

* @return

*/

private Bitmap getBitmapFromFile(String url){

Bitmap bitmap = null;

String fileName = getMD5Str(url);

if(fileName == null)

return null;

String filePath = cachedDir + "/" + fileName;

try {

FileInputStream fis = new FileInputStream(filePath);

bitmap = BitmapFactory.decodeStream(fis);

} catch (FileNotFoundException e) {

e.printStackTrace();

bitmap = null;

}

return bitmap;

}

/**

* MD5 加密

*/

private static String getMD5Str(String str) {

MessageDigest messageDigest = null;

try {

messageDigest = MessageDigest.getInstance("MD5");

messageDigest.reset();

messageDigest.update(str.getBytes("UTF-8"));

} catch (NoSuchAlgorithmException e) {

System.out.println("NoSuchAlgorithmException caught!");

return null;

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

return null;

}

byte[] byteArray = messageDigest.digest();

StringBuffer md5StrBuff = new StringBuffer();

for (int i = 0; i 

if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)

md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));

else

md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));

}

return md5StrBuff.toString();

}

/**

* MD5 加密

private static String getMD5Str(Object...objects){

StringBuilder stringBuilder=new StringBuilder();

for (Object object : objects) {

stringBuilder.append(object.toString());

}

return getMD5Str(stringBuilder.toString());

}*/

}

3.测试Activity

package com.imagecache;

import android.app.Activity;

import android.graphics.Bitmap;

import android.os.Bundle;

import android.widget.ImageView;

public class MainActivity extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final ImageView iv = (ImageView)findViewById(R.id.iv);

//网络图片地址

String imgUrl = "http://...";

//for test

AsyncImageLoader loader = new AsyncImageLoader(getApplicationContext());

//将图片缓存至外部文件中

loader.setCache2File(true); //false

//设置外部缓存文件夹

loader.setCachedDir(this.getCacheDir().getAbsolutePath());

//下载图片,第二个参数是否缓存至内存中

loader.downloadImage(imgUrl, true/*false*/, new AsyncImageLoader.ImageCallback() {

@Override

public void onImageLoaded(Bitmap bitmap, String imageUrl) {

if(bitmap != null){

iv.setImageBitmap(bitmap);

}else{

//下载失败,设置默认图片

}

}

});

}

}转自:http://blog.csdn.net/liliang497/article/details/7221110

原文:http://www.cnblogs.com/pricks/p/3921611.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java多线程下载网络图片的实现方法如下: 1. 定义一个DownloadTask类,用于表示一个下载任务,其中包含下载的URL、存储路径和线程数等信息。 2. 在DownloadTask类中实现Runnable接口,并重写run()方法,在该方法中实现下载图片的逻辑,可以使用URLConnection或者HttpClient等工具类进行网络请求,并将下载的数据写入本地文件。 3. 在DownloadTask类中定义一个download()方法,用于启动下载任务,该方法将根据线程数划分下载任务,并启动多个线程进行下载。 4. 在应用程序主方法中创建DownloadTask对象,并调用download()方法启动下载任务。 下面是一个简单的Java多线程下载网络图片的示例代码: ```java import java.io.*; import java.net.*; import java.util.concurrent.*; public class DownloadTask implements Runnable { private String url; private String file; private int threadCount; public DownloadTask(String url, String file, int threadCount) { this.url = url; this.file = file; this.threadCount = threadCount; } public void run() { try { URLConnection conn = new URL(url).openConnection(); int contentLength = conn.getContentLength(); System.out.println("Total size: " + contentLength); RandomAccessFile raf = new RandomAccessFile(file, "rw"); raf.setLength(contentLength); ExecutorService executor = Executors.newFixedThreadPool(threadCount); for (int i = 0; i < threadCount; i++) { long start = (long) i * contentLength / threadCount; long end = (long) (i + 1) * contentLength / threadCount - 1; executor.execute(new DownloadThread(url, file, start, end)); } executor.shutdown(); executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES); System.out.println("Download completed."); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { String url = "http://www.example.com/image.jpg"; String file = "image.jpg"; int threadCount = 4; DownloadTask task = new DownloadTask(url, file, threadCount); task.download(); } } class DownloadThread implements Runnable { private String url; private String file; private long start; private long end; public DownloadThread(String url, String file, long start, long end) { this.url = url; this.file = file; this.start = start; this.end = end; } public void run() { try { HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection(); conn.setRequestMethod("GET"); conn.setRequestProperty("Range", "bytes=" + start + "-" + end); conn.setConnectTimeout(5000); conn.setReadTimeout(5000); InputStream in = conn.getInputStream(); RandomAccessFile raf = new RandomAccessFile(file, "rw"); raf.seek(start); byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) { raf.write(buffer, 0, len); } raf.close(); in.close(); System.out.println("Part downloaded: " + start + "-" + end); } catch (Exception e) { e.printStackTrace(); } } } ``` 在上述代码中,DownloadTask类表示一个下载任务,其中包含下载的URL、存储路径和线程数等信息。在run()方法中实现下载图片的逻辑,将根据线程数划分下载任务,并启动多个线程进行下载。DownloadThread类表示一个下载线程,其中包含下载的URL、存储路径和下载的起始和结束位置等信息。在run()方法中实现下载数据的逻辑,使用HttpURLConnection发送请求,并将下载的数据写入本地文件。 在应用程序主方法中,创建DownloadTask对象,并调用download()方法启动下载任务。其中,url表示要下载图片URL,file表示要保存的本地文件路径,threadCount表示下载线程数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值