java图片加载是异步的吗_java_在Android的应用中实现网络图片异步加载的方法,前言 其实很幸运,入职一周 - phpStudy...

在Android的应用中实现网络图片异步加载的方法

前言其实很幸运,入职一周之后就能跟着两个师兄做android开发,师兄都是大神,身为小白的我只能多多学习,多多努力。最近一段时间都忙的没机会总结,今天刚完成了android客户端图片异步加载的类,这里记录一下(ps:其实我这里都是参考网上开源实现)

原理在ListView或者GridView中加载图片的原理基本都是一样的:

先从内存缓存中获取,取到则返回,取不到进行下一步

从文件缓存中获取,取到则返回并更新到内存缓存,取不到则进行进行下一步

从网络上下载图片,并更新内存缓存和文件缓存

流程图如下:

同时,要注意线程的数量。一般在listview中加载图片,大家都是开启新的线程去加载,但是当快速滑动时,很容易造成OOM,因此需要控制线程数量。我们可以通过线程池控制线程的数量,具体线程池的大小还需要根据处理器的情况和业务情况自行判断

建立线程池的方法如下:

ExecutorService executorService = Executors.newFixedThreadPool(5); // 5是可变的

文件缓存类

import java.io.File;

import android.content.Context;

public class FileCache {

private static final String DIR_NAME = "your_dir";

private File cacheDir;

public FileCache(Context context) {

// Find the directory to save cached images

if (android.os.Environment.getExternalStorageState().equals(

android.os.Environment.MEDIA_MOUNTED)) {

cacheDir = new File(

android.os.Environment.getExternalStorageDirectory(),

DIR_NAME);

} else {

cacheDir = context.getCacheDir();

}

if (!cacheDir.exists()) {

cacheDir.mkdirs();

}

}

public File getFile(String url) {

// Identify images by url's hash code

String filename = String.valueOf(url.hashCode());

File f = new File(cacheDir, filename);

return f;

}

public void clear() {

File[] files = cacheDir.listFiles();

if (files == null) {

return;

} else {

for (File f : files) {

f.delete();

}

}

}

}

内存缓存类这里使用了软引用,Map> cache,可以google一下软引用的机制,简单的说:实现了map,同时当内存紧张时可以被回收,不会造成内存泄露

import java.lang.ref.SoftReference;

import java.util.Collections;

import java.util.LinkedHashMap;

import java.util.Map;

import android.graphics.Bitmap;

public class MemoryCache {

private Map> cache = Collections

.synchronizedMap(new LinkedHashMap>(

10, 1.5f, true));

public Bitmap get(String id) {

if (!cache.containsKey(id)) {

return null;

}

SoftReference ref = cache.get(id);

return ref.get();

}

public void put(String id, Bitmap bitmap) {

cache.put(id, new SoftReference(bitmap));

}

public void clear() {

cache.clear();

}

}

图片加载类

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.HttpURLConnection;

import java.net.URL;

import java.util.Collections;

import java.util.Map;

import java.util.WeakHashMap;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.os.Handler;

import android.widget.ImageView;

public class ImageLoader {

/**

* Network time out

*/

private static final int TIME_OUT = 30000;

/**

* Default picture resource

*/

private static final int DEFAULT_BG = R.drawable.plate_list_head_bg;

/**

* Thread pool number

*/

private static final int THREAD_NUM = 5;

/**

* Memory image cache

*/

MemoryCache memoryCache = new MemoryCache();

/**

* File image cache

*/

FileCache fileCache;

/**

* Judge image view if it is reuse

*/

private Map imageViews = Collections

.synchronizedMap(new WeakHashMap());

/**

* Thread pool

*/

ExecutorService executorService;

/**

* Handler to display images in UI thread

*/

Handler handler = new Handler();

public ImageLoader(Context context) {

fileCache = new FileCache(context);

executorService = Executors.newFixedThreadPool(THREAD_NUM);

}

public void disPlayImage(String url, ImageView imageView) {

imageViews.put(imageView, url);

Bitmap bitmap = memoryCache.get(url);

if (bitmap != null) {

// Display image from Memory cache

imageView.setImageBitmap(bitmap);

} else {

// Display image from File cache or Network

queuePhoto(url, imageView);

}

}

private void queuePhoto(String url, ImageView imageView) {

PhotoToLoad photoToLoad = new PhotoToLoad(url, imageView);

executorService.submit(new PhotosLoader(photoToLoad));

}

private Bitmap getBitmap(String url) {

File f = fileCache.getFile(url);

// From File cache

Bitmap bmp = decodeFile(f);

if (bmp != null) {

return bmp;

}

// From Network

try {

Bitmap bitmap = null;

URL imageUrl = new URL(url);

HttpURLConnection conn = (HttpURLConnection) imageUrl

.openConnection();

conn.setConnectTimeout(TIME_OUT);

conn.setReadTimeout(TIME_OUT);

conn.setInstanceFollowRedirects(true);

InputStream is = conn.getInputStream();

OutputStream os = new FileOutputStream(f);

copyStream(is, os);

os.close();

conn.disconnect();

bitmap = decodeFile(f);

return bitmap;

} catch (Throwable ex) {

if (ex instanceof OutOfMemoryError) {

clearCache();

}

return null;

}

}

private void copyStream(InputStream is, OutputStream os) {

int buffer_size = 1024;

try {

byte[] bytes = new byte[buffer_size];

while (true) {

int count = is.read(bytes, 0, buffer_size);

if (count == -1) {

break;

}

os.write(bytes, 0, count);

}

} catch (Exception e) {

}

}

private Bitmap decodeFile(File f) {

try {

// TODO:Compress image size

FileInputStream fileInputStream = new FileInputStream(f);

Bitmap bitmap = BitmapFactory.decodeStream(fileInputStream);

return bitmap;

} catch (FileNotFoundException e) {

return null;

}

}

private void clearCache() {

memoryCache.clear();

fileCache.clear();

}

/**

* Task for the queue

*

* @author zhengyi.wzy

*

*/

private class PhotoToLoad {

public String url;

public ImageView imageView;

public PhotoToLoad(String url, ImageView imageView) {

this.url = url;

this.imageView = imageView;

}

}

/**

* Asynchronous to load picture

*

* @author zhengyi.wzy

*

*/

class PhotosLoader implements Runnable {

PhotoToLoad photoToLoad;

public PhotosLoader(PhotoToLoad photoToLoad) {

this.photoToLoad = photoToLoad;

}

private boolean imageViewReused(PhotoToLoad photoToLoad) {

String tag = imageViews.get(photoToLoad.imageView);

if (tag == null || !tag.equals(photoToLoad.url)) {

return true;

}

return false;

}

@Override

public void run() {

// Abort current thread if Image View reused

if (imageViewReused(photoToLoad)) {

return;

}

Bitmap bitmap = getBitmap(photoToLoad.url);

// Update Memory

memoryCache.put(photoToLoad.url, bitmap);

if (imageViewReused(photoToLoad)) {

return;

}

// Don't change UI in children thread

BitmapDisplayer bd = new BitmapDisplayer(bitmap, photoToLoad);

handler.post(bd);

}

class BitmapDisplayer implements Runnable {

Bitmap bitmap;

PhotoToLoad photoToLoad;

public BitmapDisplayer(Bitmap bitmap, PhotoToLoad photoToLoad) {

this.bitmap = bitmap;

this.photoToLoad = photoToLoad;

}

@Override

public void run() {

if (imageViewReused(photoToLoad)) {

return;

}

if (bitmap != null) {

photoToLoad.imageView.setImageBitmap(bitmap);

} else {

photoToLoad.imageView.setImageResource(DEFAULT_BG);

}

}

}

}

}

调用方法

ImageLoader imageLoader = new ImageLoader(context);

imageLoader.disPlayImage(imageUrl, imageView);相关阅读:

Android网络数据开关用法简单示例

JavaScript中的Object对象学习教程

C#使用GDI画圆的方法

javascript获取网页宽高方法汇总

整理HTML5的一些新特性与Canvas的常用属性

fedora 11下安装使用rar的方法

C#将Excel中的数据转换成DataSet

Windows10正式版多任务管理都有哪些功能?Win10多任务管理功能介绍

jqGrid日期格式的判断示例代码(开始日期与结束日期)

XP系统下如何找回被EFS加密过的文件

7月29日 微软宣布Win10商店已向开发者正式开放

Nodejs的express使用教程

nodejs npm install全局安装和本地安装的区别

Windows7如何查看回收站对应的文件夹有哪些方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值