java异步下载图片_异步下载图片+图片缓存

这个博客介绍了一个名为RemoteImageView的自定义控件,用于Java中异步下载图片并实现图片缓存功能。它包含图片下载的重试机制、内存和文件系统的缓存策略,以及根据设定的缓存大小清理过期文件的方法。
摘要由CSDN通过智能技术生成

publicclass RemoteImageView extends ImageView {

private Context mContext;

privatestaticint mCacheSize = 150; // 设置的缓存大小。

privatestaticfinalint MAX_FAILURES = 3; // 下载的尝试请求次数

privateint mFailure; // 下载失败次数

private String mUrl; // 当前下载的url

private String mCurrentlyGrabbedUrl; // 当前下载成功的url

privatefinalstatic String JAMENDO_DIR = "Android/data/com.teleca.jamendo"; // 文件缓存存放的路径.

privatefinalstaticlong MB = 1073741824;

public RemoteImageView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

mContext = context;

}

public RemoteImageView(Context context, AttributeSet attrs) {

super(context, attrs);

mContext = context;

}

public RemoteImageView(Context context) {

super(context);

mContext = context;

}

/**

* 设置默认图片

*/

publicvoid setDefaultImage(Integer resid) {

setImageResource(resid);

}

/**

* 设置需要异步加载的图片

*/

publicvoid setImageUrl(String url) {

// 下载失败进行重试,如果重试次数超过规定的限制,则直接返回.

if (mUrl != null

&& mUrl.equals(url)

&& (mCurrentlyGrabbedUrl == null || (mCurrentlyGrabbedUrl != null && !mCurrentlyGrabbedUrl

.equals(url)))) {

mFailure++;

if (mFailure > MAX_FAILURES) {

Log.e(RemoteImageApplication.TAG, "下载该图片地址失败:" + url);

return;

}

} else {

mUrl = url;

mFailure = 0;

}

ImageCache p_w_picpathCache = RemoteImageApplication.getInstance()

.getImageCache();

if (p_w_picpathCache.isCached(url)) {

setImageBitmap(p_w_picpathCache.get(url));

} else {

// 如果内存中没有该缓存,则从文件中进行查找.

String fileName = convertUrlToFileName(url); // 进行文件名处理

String filepath = getDirectory(fileName); // 取得缓存文件夹目录

String pathFileName = filepath + "/" + fileName; // 组拼文件

File pathFile = new File(pathFileName);

if (!pathFile.exists()) {

try {

pathFile.createNewFile();

} catch (IOException e) {

Log.d(RemoteImageApplication.TAG, "创建图片文件失败:"

+ pathFileName);

}

}

Bitmap tbmp = BitmapFactory.decodeFile(pathFileName);

if (tbmp == null) {

Log.d(RemoteImageApplication.TAG, "图片文件不存在,开始进行下载");

try {

new DownloadTask().execute(url);

} catch (RejectedExecutionException e) {

Log.d(RemoteImageApplication.TAG, "下载失败");

}

} else {

Log.i(RemoteImageApplication.TAG, "从文件中加载图片");

RemoteImageApplication.getInstance().getImageCache()

.put(url, tbmp);

this.setImageBitmap(tbmp);

}

updateCacheSize(pathFileName); // 进行检测文件大小,以便于清除缓存.

}

}

privatevoid updateCacheSize(String pathFileName) {

// TODO Auto-generated method stub

updateSizeCache(pathFileName);

}

/**

* 检查文件目录是否超过规定的缓存大小

*

* @param fileName

*/

privatevoid updateSizeCache(String pathFileName) {

// TODO Auto-generated method stub

mCacheSize = PreferenceManager.getDefaultSharedPreferences(mContext)

.getInt(RemoteSettings.CACHE_SIZE, 100); // 读取设置的缓存大小,前台可以动态设置此值

if (isSDCardEnable()) {

String extStorageDirectory = Environment

.getExternalStorageDirectory().toString(); // 取得SD根路径

String dirPath = extStorageDirectory + "/" + JAMENDO_DIR

+ "/p_w_picpathcache";

File dirFile = new File(dirPath);

File[] files = dirFile.listFiles();

long dirSize = 0;

for (File file : files) {

dirSize += file.length();

}

if (dirSize > mCacheSize * MB) {

clearCache();

}

}

}

/**

* 异步下载图片

*

* @ClassName: DownloadTask

* @author 姜涛

* @version 1.0 2012-1-15 下午5:06:21

*/

class DownloadTask extends AsyncTask {

private String mTaskUrl;

private Bitmap mBmp = null;

@Override

publicvoid onPreExecute() {

// loadDefaultImage();

super.onPreExecute();

}

@Override

public String doInBackground(String... params) {

mTaskUrl = params[0];

InputStream stream = null;

URL p_w_picpathUrl;

Bitmap bmp = null;

try {

p_w_picpathUrl = new URL(mTaskUrl);

try {

stream = p_w_picpathUrl.openStream();

bmp = BitmapFactory.decodeStream(stream);

try {

if (bmp != null) {

mBmp = bmp;

RemoteImageApplication.getInstance()

.getImageCache().put(mTaskUrl, bmp);

Log.d(RemoteImageApplication.TAG,

"图片缓存到application中: " + mTaskUrl);

}

} catch (NullPointerException e) {

Log.w(RemoteImageApplication.TAG, "下载失败,图片为空:"

+ mTaskUrl);

}

} catch (IOException e) {

Log.w(RemoteImageApplication.TAG, "无法加载该url:" + mTaskUrl);

} finally {

try {

if (stream != null) {

stream.close();

}

} catch (IOException e) {

}

}

} catch (MalformedURLException e) {

e.printStackTrace();

}

return mTaskUrl;

}

@Override

publicvoid onPostExecute(String url) {

super.onPostExecute(url);

Bitmap bmp = RemoteImageApplication.getInstance().getImageCache()

.get(url);

if (bmp == null) {

Log.w(RemoteImageApplication.TAG, "尝试重新下载:" + url);

RemoteImageView.this.setImageUrl(url);

} else {

RemoteImageView.this.setImageBitmap(bmp);

mCurrentlyGrabbedUrl = url;

saveBmpToSd(mBmp, url);

}

}

};

/**

* 把图片保存到本地

*

* @param bm

* @param url

*/

privatevoid saveBmpToSd(Bitmap bm, String url) {

if (bm == null) {

return;

}

if (mCacheSize == 0) {

return;

}

String filename = convertUrlToFileName(url);

String dir = getDirectory(filename);

File file = new File(dir + "/" + filename);

try {

file.createNewFile();

OutputStream outStream = new FileOutputStream(file);

bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);

outStream.flush();

outStream.close();

Log.i(RemoteImageApplication.TAG, "图片已保存到sd卡");

} catch (FileNotFoundException e) {

Log.w(RemoteImageApplication.TAG, "无法找到文件目录");

} catch (IOException e) {

Log.w(RemoteImageApplication.TAG, "操作文件出错");

}

}

/**

* 组拼文件名,后缀名用dat代替,避免别人使用图片管理器搜索出这种对于她们无用的图片.

*

* @param url

* @return

*/

private String convertUrlToFileName(String url) {

String filename = url;

filename = filename.replace("http://", "");

filename = filename.replace("/", ".");

filename = filename.replace(":", ".");

filename = filename.replace("jpg", "dat");

filename = filename.replace("png", "dat");

return filename;

}

/**

* 返回缓存图片所存放的文件夹

*

* @param filename

* @return

*/

private String getDirectory(String filename) {

String extStorageDirectory = Environment.getExternalStorageDirectory()

.toString(); // 取得SD根路径

String dirPath = extStorageDirectory + "/" + JAMENDO_DIR

+ "/p_w_picpathcache";

File dirFile = new File(dirPath);

if (!dirFile.exists()) {

dirFile.mkdirs();

}

return dirPath;

}

/**

* 清除缓存

*/

privatevoid clearCache() {

if (isSDCardEnable()) {

String extStorageDirectory = Environment

.getExternalStorageDirectory().toString(); // 取得SD根路径

String dirPath = extStorageDirectory + "/" + JAMENDO_DIR

+ "/p_w_picpathcache";

File dir = new File(dirPath);

File[] files = dir.listFiles(); // 取得该目录下的所有文件

if (files == null || files.length == 0) {

return;

}

for (File file : files) {

file.delete();

}

Log.d(RemoteImageApplication.TAG, "已清除缓存:" + dirPath);

}

}

/**

* 判断SD卡是否可用

*/

publicstaticboolean isSDCardEnable() {

return Environment.getExternalStorageState().equals(

Environment.MEDIA_MOUNTED);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值