版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】Android实现异步加载图片
麦洛开通博客以来,有一段时间没有更新博文了.主要是麦洛这段时间因项目开发实在太忙了.今天周六还在公司加班,苦逼程序猿都是这样生活的.今天在做项目的时候,有一个实现异步加载图片的功能,虽然比较简单但还是记录一下吧.因为麦洛之前实现异步加载图片都是使用了AsynTask这个API,继续这个类,实现起来非常简单也很方便.在doInBackground()方法里实现下载逻辑.具体实现如下实现逻辑是:先从内存中读取,如果内存中有这张图片,则直接使用;如果内存没有再到sdcard上读取,如果有则显示;如果sdcard上还没有则到网络上读取.内存中开启缓存是参考了网上的实现.麦洛在这里非常感谢喜欢分享的程序猿们.public
class
ImageDownloader
extends
AsyncTask<String,
Integer,
Object>
{
private
static
final
String
TAG
=
"ImageDownloader";
//
为了加快速度,在内存中开启缓存(主要应用于重复图片较多时,或者同一个图片要多次被访问,比如在ListView时来回滚动)
private
Map<String,
SoftReference<Drawable>>
p_w_picpathCache
=
new
HashMap<String,
SoftReference<Drawable>>();
/**
*
显示图片的控件
*/
private
ImageView
mImageView;
public
ImageDownloader(ImageView
p_w_picpath)
{
mImageView
=
p_w_picpath;
}
@Override
protected
void
onPreExecute()
{
super.onPreExecute();
}
@Override
protected
Object
doInBackground(String...
params)
{
//
Log.i("ImageDownloader",
"loading
p_w_picpath...");
String
url
=
params[0];
Drawable
drawable
=
null;
try
{
if
(!"".equals(url)
&&
url
!=
null)
{
String
fileName
=
url.hashCode()+".jpg";
//
如果缓存过就从缓存中取出数据
if
(p_w_picpathCache.containsKey(fileName))
{
SoftReference<Drawable>
softReference
=
p_w_picpathCache.get(fileName);
drawable
=
softReference.get();
if
(drawable
!=
null)
{
return
drawable;
}
}
File
dir
=
new
File(FileConstant.IMAGE_FILE_PATH);
if
(!dir.exists())
{
boolean
m
=
dir.mkdirs();
}
File
file
=
new
File(dir,
fileName);
if
(file.exists()
&&
file.length()
>
0)
{
Log.i(TAG,
"load
p_w_picpath
from
sd
card");
//
如果文件存在则直接读取sdcard
drawable
=
readFromSdcard(file);
}
else
{
//file.createNewFile();
Log.i(TAG,
"load
p_w_picpath
from
network");
URL
p_w_picpathUrl
=
new
URL(url);
//
写入sdcard
if
(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
saveImageFile(p_w_picpathUrl,
file);
drawable
=
Drawable.createFromStream(new
FileInputStream(file),
fileName);
}else{
//直接从流读取
drawable
=
Drawable.createFromStream(p_w_picpathUrl.openStream(),
fileName);
}
}
if(drawable!=null){
//保存在缓存中
p_w_picpathCache.put(fileName,
new
SoftReference<Drawable>(drawable));
}
}
}
catch
(Exception
e)
{
e.printStackTrace();
}
return
drawable;
}
/**
*
save
p_w_picpath*/
private
void
saveImageFile(URL
url,
File
file)
{
FileOutputStream
out
=
null;
InputStream
in
=
null;
try
{
file.deleteOnExit();
out
=
new
FileOutputStream(file);
in
=
url.openStream();
byte[]
buf
=
new
byte[1024];
int
len
=
-1;
while((len
=
in.read(buf))!=-1){
out.write(buf,
0,
len);
out.flush();
}
}
catch
(Exception
e)
{
e.printStackTrace();
}
finally
{
if(out!=null){
try
{
out.close();
}
catch
(IOException
e)
{
e.printStackTrace();
}
}
if(in!=null){
try
{
in.close();
}
catch
(IOException
e)
{
e.printStackTrace();
}
}
}
}
/**
*
从sdcard中获取图片*/
private
Drawable
readFromSdcard(File
file)
throws
Exception
{
FileInputStream
in
=
new
FileInputStream(file);
return
Drawable.createFromStream(in,
file.getName());
}
@Override
protected
void
onPostExecute(Object
result)
{
super.onPostExecute(result);
Drawable
drawable
=
(Drawable)
result;
if
(mImageView
!=
null
&&
drawable
!=
null)
{
mImageView.setBackgroundDrawable(drawable);
}
}
@Override
protected
void
onProgressUpdate(Integer...
values)
{
super.onProgressUpdate(values);
}
@Override
protected
void
onCancelled()
{
super.onCancelled();
}
}使用时:ImageDownloader
loader
=
new
ImageDownloader(p_w_picpathView);
loader.execute(url);其实这样的话,还有一些隐患的,就是说这个类实现还是有些问题的.比如每次都在p_w_picpathView中设置网络上的图片时,其实是没有使用到这个类里面的内存缓存的,就是p_w_picpathCacheMap<String,
SoftReference<Drawable>>
p_w_picpathCache
=
new
HashMap<String,
SoftReference<Drawable>>();因为每次设置p_w_picpathView的时候,都是new了一个ImageDownloader的对象.所以每个ImageDownloader对象里面都是独立的一个p_w_picpathCache.
另外,AsynTask也是一个线程.而每次使用都开一个线程来load图片,对线程个数没有进行显示,毕竟线程数目还是有限制的.所以麦洛今天发现了这个问题,于是参考了别人的实现,使用了线程池,实现逻辑也上面的代码一样,先从内存读取,如果没有到sdcard读取,如果还是没有,则是网络读取;实现没有使用AsynTask,具体代码如下:/**
*
异步加载图片,并将图片设置到ImageView控件中*/public
class
ImageDownloader
extends
AsyncTask<String,
Integer,
Object>
{
private
static
final
String
TAG
=
"ImageDownloader";
//
为了加快速度,在内存中开启缓存(主要应用于重复图片较多时,或者同一个图片要多次被访问,比如在ListView时来回滚动)
private
Map<String,
SoftReference<Drawable>>
p_w_picpathCache
=
new
HashMap<String,
SoftReference<Drawable>>();
/**
*
显示图片的控件
*/
private
ImageView
mImageView;
public
ImageDownloader(ImageView
p_w_picpath)
{
mImageView
=
p_w_picpath;
}
@Override
protected
void
onPreExecute()
{
super.onPreExecute();
}
@Override
protected
Object
doInBackground(String...
params)
{
//
Log.i("ImageDownloader",
"loading
p_w_picpath...");
String
url
=
params[0];
Drawable
drawable
=
null;
try
{
if
(!"".equals(url)
&&
url
!=
null)
{
String
fileName
=
url.hashCode()+".jpg";
//
如果缓存过就从缓存中取出数据
if
(p_w_picpathCache.containsKey(fileName))
{
SoftReference<Drawable>
softReference
=
p_w_picpathCache.get(fileName);
drawable
=
softReference.get();
if
(drawable
!=
null)
{
return
drawable;
}
}
File
dir
=
new
File(FileConstant.IMAGE_FILE_PATH);
if
(!dir.exists())
{
boolean
m
=
dir.mkdirs();
}
File
file
=
new
File(dir,
fileName);
if
(file.exists()
&&
file.length()
>
0)
{
Log.i(TAG,
"load
p_w_picpath
from
sd
card");
//
如果文件存在则直接读取sdcard
drawable
=
readFromSdcard(file);
}
else
{
//file.createNewFile();
Log.i(TAG,
"load
p_w_picpath
from
network");
URL
p_w_picpathUrl
=
new
URL(url);
//
写入sdcard
if
(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
saveImageFile(p_w_picpathUrl,
file);
drawable
=
Drawable.createFromStream(new
FileInputStream(file),
fileName);
}else{
//直接从流读取
drawable
=
Drawable.createFromStream(p_w_picpathUrl.openStream(),
fileName);
}
}
if(drawable!=null){
//保存在缓存中
p_w_picpathCache.put(fileName,
new
SoftReference<Drawable>(drawable));
}
}
}
catch
(Exception
e)
{
e.printStackTrace();
}
return
drawable;
}
/**
*
save
p_w_picpath*/
private
void
saveImageFile(URL
url,
File
file)
{
FileOutputStream
out
=
null;
InputStream
in
=
null;
try
{
file.deleteOnExit();
out
=
new
FileOutputStream(file);
in
=
url.openStream();
byte[]
buf
=
new
byte[1024];
int
len
=
-1;
while((len
=
in.read(buf))!=-1){
out.write(buf,
0,
len);
out.flush();
}
}
catch
(Exception
e)
{
e.printStackTrace();
}
finally
{
if(out!=null){
try
{
out.close();
}
catch
(IOException
e)
{
e.printStackTrace();
}
}
if(in!=null){
try
{
in.close();
}
catch
(IOException
e)
{
e.printStackTrace();
}
}
}
}
/**
*
从sdcard中获取图片
*/
private
Drawable
readFromSdcard(File
file)
throws
Exception
{
FileInputStream
in
=
new
FileInputStream(file);
return
Drawable.createFromStream(in,
file.getName());
}
@Override
protected
void
onPostExecute(Object
result)
{
super.onPostExecute(result);
Drawable
drawable
=
(Drawable)
result;
if
(mImageView
!=
null
&&
drawable
!=
null)
{
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 如何快速让学生快速融入新课标
- Unit 1 Hit it big课件三年级英语上册外研版
- 澳牧品牌推广方案
- 安全管理制度汇编
- 别墅电梯市场供需现状分析及前景趋势预测报告模板
- 基于JavaEE的人事公司管理系统的设计与实现
- 【市级优课】读诗韵赏诗情悟诗魂-《春望》教学设计
- 2.3 声的利用课件学习
- 建筑制图与识图教学课件:第二章 正投影基础
- 记账实操-纺织店账务处理分录
- 乳制品食品安全管理制度.doc
- 第5章数字影像与特征提取
- 钢筋焊接工艺性试验报告
- 吃零食弊大还是利大辩论赛
- 事业单位法人开办资金确认证明
- CPIII软件使用说明书
- 蜻蜓飞飞教案
- 儿童主题商业案例研究报告课件
- 最完整工资条模板
- 中学历史学科评价方案
- (完整word版)离婚协议书最简单范本
评论
0/150
提交评论