【移动应用开发技术】Android 实现异步加载图片_第1页
【移动应用开发技术】Android 实现异步加载图片_第2页
【移动应用开发技术】Android 实现异步加载图片_第3页
【移动应用开发技术】Android 实现异步加载图片_第4页
【移动应用开发技术】Android 实现异步加载图片_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论