异步下载图片+图片缓存
功能如下:
流程如下:
RemoteImageViewActivity:
publicclass RemoteImageViewActivity extends Activity {
/** Called when the activity is first created. */
@Override
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
RemoteImageView img = (RemoteImageView) findViewById(R.id.remote_img);
img.setDefaultImage(R.drawable.ic_launcher);
img.setImageUrl("http://img2.kwcdn.kuwo.cn:81/star/albumcover/120/7/8/83787_1323997225.jpg");
}
@Override
protectedvoid onPause() {
// TODO Auto-generated method stub
super.onPause();
}
}
ImageCache:
publicclass ImageCache extends WeakHashMap<String, Bitmap>{
/**
* 判断该url是否存在
* @param url
* @return
*/
publicboolean isCached(String url){
return containsKey(url) && get(url) != null;
}
}
RemoteImageApplication:
publicclass RemoteImageApplication extends Application {
publicstaticfinal String TAG = "RemoteImageApplication";
privatestatic RemoteImageApplication application;
private ImageCache mImageCache;
public SharedPreferences prefs = null;
publicstatic RemoteImageApplication getInstance() {
return application;
}
@Override
publicvoid onCreate() {
// TODO Auto-generated method stub
super.onCreate();
application = this;
mImageCache = new ImageCache();
prefs = PreferenceManager.getDefaultSharedPreferences(this);
}
public ImageCache getImageCache() {
return mImageCache;
}
}
RemoteSettings:
publicclass RemoteSettings {
publicstaticfinal String CACHE_SIZE = "cache_size"; //图片缓存保留大小,如果超过该大小,即进行自动清除缓存.
}
RemoteImageView:
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<String, Void, String> {
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);
}
}
本文转自:http://lewisliu.iteye.com/blog/1346820
转载于:https://blog.51cto.com/1509623/1388464
异步下载图片+图片缓存相关推荐
- 使用开源库 SDWebImage 异步下载缓存图片(持续更新)
source https://github.com/rs/SDWebImage APIdoc http://hackemist.com/SDWebImage/doc Asynchronous im ...
- [Swift]在不依赖三方库的情况下如何异步下载和缓存图片?
在可滚动视图(如UITableView)中异步加载大量图片是一个很常见的任务. 然而,在图片正在下载的同时又要保持应用程序流畅滚动,可能有点挑战. 许多开发人员依靠像Alamofire和SDWebIm ...
- LruCache缓存处理及异步加载图片类的封装
Android中的缓存处理及异步加载图片类的封装 一.缓存介绍: (一).Android中缓存的必要性: 智能手机的缓存管理应用非常的普遍和需要,是提高用户体验的有效手段之一. 1.没有缓存的弊端 ...
- [置顶] 异步加载图片,使用LruCache和SD卡或手机缓存,效果非常的流畅
转载请注明出处http://blog.csdn.net/xiaanming/article/details/9825113 异步加载图片的例子,网上也比较多,大部分用了HashMap<Strin ...
- ListView中的图片异步加载、缓存
一.ListView的图片异步加载 我们都知道对每一个Weibo Item都有用户头像,而且每一条微博还可能带有图片.如果在加载列表的同时加载图片,这样有几个缺点,第一很费事,界面卡住,用户体验很不好 ...
- Android批量图片加载经典系列——使用LruCache、AsyncTask缓存并异步加载图片
一.问题描述 使用LruCache.AsyncTask实现批量图片的加载并达到下列技术要求 1.从缓存中读取图片,若不在缓存中,则开启异步线程(AsyncTask)加载图片,并放入缓存中 2.及时移除 ...
- 浅谈Android中的异步加载之ListView中图片的缓存及优化三
隔了很久没写博客,现在必须快速脉动回来.今天我还是接着上一个多线程中的异步加载系列中的最后一个使用异步加载实现ListView中的图片缓存及其优化.具体来说这次是一个综合Demo.但是个人觉得里面还算 ...
- Android:ViewPager详细解释(异步网络负载图片,有图片缓存,)并与导航点
android 应用.准则欢迎页面. 和图像旋转木马特征, 或者没有很多其他的内容显示在一个页面.以被划分成多个页面,在这一刻viewpager这是非常容易使用. 首先看下效果: 以下是一个样例.带异 ...
- Android中的缓存处理及异步加载图片类的封装
一.缓存介绍: (一).Android中缓存的必要性: 智能手机的缓存管理应用非常的普遍和需要,是提高用户体验的有效手段之一. 1.没有缓存的弊端: 流量开销:对于客户端--服务器端应用,从远程获取图 ...
- android异步加载图片并缓存到内存和sd卡上,Android批量图片加载经典系列——采用二级缓存、异步加载网络图片...
http://www.cnblogs.com/jerehedu/p/4560119.html 2015-06-08 09:20 by 杰瑞教育, 232 阅读, 1 评论, 收藏, 编辑一.问题描述 ...
最新文章
- VClient 无法连接Vcenter
- Linux下的/bin、/sbin、/usr/bin、/usr/sbin目录
- java解决策略膨胀_折腾Java设计模式之策略模式
- [mybatis]缓存_缓存有关的设置以及属性
- html5中折叠面板,Ant Design中折叠面板Collapse
- linux命令-tar命令
- 中国风冬日节日必备梅花PNG免扣素材
- 网络通信 route(公司局域网配置)
- 我在30岁之前做了三件骄傲的事
- CSU - 1803 数论GCD
- JS判断字符串变量是否含有某个字串的实现方法
- 如何免费搭建自己的个人网站
- 三星n8000平板_三星n8000拆机方法介绍【图解】
- php蘑菇街商城源码,php源码:dedecms精仿蘑菇街(mogujie.com)源码,时尚购物社区源码...
- 一文详解被阿里腾讯视作核心机密的大数据平台架构
- Online Generation of Collision-Free Trajectories for Quadrotor Flight in Unknown Cluttered Environme
- Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception
- python语言中整数1010的二进制是多少_10的二进制是多少哦啊?怎么算 O(∩_∩)O谢谢?...
- (一)理解word2vec:原理篇
- 小滕要开始学习C语言啦
热门文章
- linux 内存性能评估,linux的内存性能评估
- 大工18春计算机原理在线作业答案,大工13春《计算机组成原理》在线作业2 及答案...
- 去掉重复值php,php多维数组去掉重复值
- mysql数据库存储过程语法错误_奇怪的mysql创建存储过程语法错误
- lua劈分字符串方法及实例
- 【转】彻底理解安卓里的ldpi、mdpi、hdpi、xhdpi、xxhdpi文件夹含义
- RMAN使用备份传输表空间
- Linux下搭建DNS 服务器
- 20天精通 Windows 8:系列课程资料集
- nagios常见错误及页面错误