700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > android 图片加载 软引用_Android 异步加载网络图片并缓存到本地 软引用 学习分享(转)...

android 图片加载 软引用_Android 异步加载网络图片并缓存到本地 软引用 学习分享(转)...

时间:2023-05-05 17:51:10

相关推荐

android 图片加载 软引用_Android 异步加载网络图片并缓存到本地 软引用 学习分享(转)...

迪 王. 于 星期四, 20/02/ - 21:36 提交

在android应用开发的时候,加载网络图片是一个非常重要的部分,很多图片不可能放在本地,所以就必须要从服务器或者网络读取图片。

软引用是一个现在非常流行的方法,用户体验比较好,不用每次都需要从网络下载图片,如果下载后就存到本地,下次读取时首先查看本地有没有,如果没有再从网络读取。

记得2月份在和爱奇艺公司的项目总监一起搞联通的OTT盒子的时候他就提了一下软引用,奇艺做的手机客户端就是采用这种方法,所以你会发现奇艺客户端占用很大的空间,下面就分享一下异步加载网络图片的方法吧。

FileCache.java

[java] view plaincopy

import java.io.File;

import android.content.Context;

public class FileCache {

private File cacheDir;

public FileCache(Context context) {

// 找一个用来缓存图片的路径

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

android.os.Environment.MEDIA_MOUNTED))

cacheDir = new File(android.os.Environment.getExternalStorageDirectory(),

"文件夹名称");

else

cacheDir = context.getCacheDir();

if (!cacheDir.exists())

cacheDir.mkdirs();

}

public File getFile(String url) {

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;

for (File f : files)

f.delete();

}

}

HttpUtil.java

[java] view plaincopy

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.io.UnsupportedEncodingException;

import .HttpURLConnection;

import .MalformedURLException;

import .ProtocolException;

import .URL;

import .URLEncoder;

import java.util.Map;

/**

* Http 请求工具类

*

* @author Scorpio.Liu

*

*/

public class HttpUtil {

/**

* 获取响应字符串

*

* @param path

* 路径

* @param parameters

* 参数

* @return 响应字符串

*/

public static String getResponseStr(String path, Map parameters) {

StringBuffer buffer = new StringBuffer();

URL url;

try {

if (parameters != null && !parameters.isEmpty()) {

for (Map.Entry entry : parameters.entrySet()) {

// 完成转码操作

buffer.append(entry.getKey()).append("=")

.append(URLEncoder.encode(entry.getValue(), "UTF-8")).append("&");

}

buffer.deleteCharAt(buffer.length() - 1);

}

url = new URL(path);

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

urlConnection.setConnectTimeout(3000);

urlConnection.setRequestMethod("POST");

urlConnection.setDoInput(true);// 表示从服务器获取数据

urlConnection.setDoOutput(true);// 表示向服务器写数据

// 获得上传信息的字节大小以及长度

byte[] mydata = buffer.toString().getBytes();

// 表示设置请求体的类型是文本类型

urlConnection.setRequestProperty("Content-Type",

"application/x-www-form-urlencoded");

urlConnection.setRequestProperty("Content-Length", String.valueOf(mydata.length));

// 获得输出流,向服务器输出数据

OutputStream outputStream = urlConnection.getOutputStream();

outputStream.write(mydata, 0, mydata.length);

outputStream.close();

int responseCode = urlConnection.getResponseCode();

if (responseCode == 200) {

return changeInputStream(urlConnection.getInputStream());

}

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

} catch (MalformedURLException e) {

e.printStackTrace();

} catch (ProtocolException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

private static String changeInputStream(InputStream inputStream) {

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

byte[] data = new byte[1024];

int len = 0;

String result = "";

if (inputStream != null) {

try {

while ((len = inputStream.read(data)) != -1) {

outputStream.write(data, 0, len);

}

result = new String(outputStream.toByteArray(), "UTF-8");

} catch (IOException e) {

e.printStackTrace();

}

}

return result;

}

public static InputStream getInputStream(String path) {

URL url;

try {

url = new URL(path);

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

urlConnection.setConnectTimeout(3000);

urlConnection.setRequestMethod("GET");

urlConnection.setDoInput(true);// 表示从服务器获取数据

urlConnection.connect();

if (urlConnection.getResponseCode() == 200)

return urlConnection.getInputStream();

} catch (MalformedURLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

public static byte[] readStream(InputStream inStream) throws Exception {

ByteArrayOutputStream outSteam = new ByteArrayOutputStream();

byte[] buffer = new byte[1024];

int len = -1;

while ((len = inStream.read(buffer)) != -1) {

outSteam.write(buffer, 0, len);

}

outSteam.close();

inStream.close();

return outSteam.toByteArray();

}

public static void CopyStream(String url, File f) {

FileOutputStream fileOutputStream = null;

InputStream inputStream = null;

try {

inputStream = getInputStream(url);

byte[] data = new byte[1024];

int len = 0;

fileOutputStream = new FileOutputStream(f);

while ((len = inputStream.read(data)) != -1) {

fileOutputStream.write(data, 0, len);

}

} catch (FileNotFoundException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {

if (inputStream != null) {

try {

inputStream.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if (fileOutputStream != null) {

try {

fileOutputStream.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

}

MemoryCache.java

[java] view plaincopy

import java.lang.ref.SoftReference;

import java.util.Collections;

import java.util.HashMap;

import java.util.Map;

import android.graphics.Bitmap;

public class MemoryCache {

private Map> cache = Collections

.synchronizedMap(new HashMap>());// 软引用

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();

}

}

ImageLoader.java

[java] view plaincopy

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.UnsupportedEncodingException;

import .URLEncoder;

import java.util.Collections;

import java.util.Map;

import java.util.WeakHashMap;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import android.app.Activity;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.drawable.BitmapDrawable;

import android.widget.ImageView;

public class ImageLoader {

private MemoryCache memoryCache = new MemoryCache();

private FileCache fileCache;

private Map imageViews = Collections

.synchronizedMap(new WeakHashMap());

private ExecutorService executorService;

private boolean isSrc;

/**

* @param context

* 上下文对象

* @param flag

* true为source资源,false为background资源

*/

public ImageLoader(Context context, boolean flag) {

fileCache = new FileCache(context);

executorService = Executors.newFixedThreadPool(5);

isSrc = flag;

}

final int stub_id = R.drawable.ic_launcher;

public void DisplayImage(String url, ImageView imageView) {

String u1 = url.substring(0, url.lastIndexOf("/") + 1);

String u2 = url.substring(url.lastIndexOf("/") + 1);

try {

u2 = URLEncoder.encode(u2, "UTF-8");

} catch (UnsupportedEncodingException e) {

e.printStackTrace();

}

url = u1 + u2;

imageViews.put(imageView, url);

Bitmap bitmap = memoryCache.get(url);

if (bitmap != null) {

if (isSrc)

imageView.setImageBitmap(bitmap);

else

imageView.setBackgroundDrawable(new BitmapDrawable(bitmap));

} else {

queuePhoto(url, imageView);

if (isSrc)

imageView.setImageResource(stub_id);

else

imageView.setBackgroundResource(stub_id);

}

}

private void queuePhoto(String url, ImageView imageView) {

PhotoToLoad p = new PhotoToLoad(url, imageView);

executorService.submit(new PhotosLoader(p));

}

private Bitmap getBitmap(String url) {

try {

File f = fileCache.getFile(url);

// 从sd卡

Bitmap b = onDecodeFile(f);

if (b != null)

return b;

// 从网络

Bitmap bitmap = null;

System.out.println("ImageLoader-->download");

HttpUtil.CopyStream(url, f);

bitmap = onDecodeFile(f);

return bitmap;

} catch (Exception ex) {

ex.printStackTrace();

return null;

}

}

public Bitmap onDecodeFile(File f) {

try {

return BitmapFactory.decodeStream(new FileInputStream(f));

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

/**

* 解码图像用来减少内存消耗

*

* @param f

* @return

*/

public Bitmap decodeFile(File f) {

try {

// 解码图像大小

BitmapFactory.Options o = new BitmapFactory.Options();

o.inJustDecodeBounds = true;

BitmapFactory.decodeStream(new FileInputStream(f), null, o);

// 找到正确的刻度值,它应该是2的幂。

final int REQUIRED_SIZE = 70;

int width_tmp = o.outWidth, height_tmp = o.outHeight;

int scale = 1;

while (true) {

if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)

break;

width_tmp /= 2;

height_tmp /= 2;

scale *= 2;

}

BitmapFactory.Options o2 = new BitmapFactory.Options();

o2.inSampleSize = scale;

return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);

} catch (FileNotFoundException e) {

}

return null;

}

/**

* 任务队列

*

* @author Scorpio.Liu

*

*/

private class PhotoToLoad {

public String url;

public ImageView imageView;

public PhotoToLoad(String u, ImageView i) {

url = u;

imageView = i;

}

}

class PhotosLoader implements Runnable {

PhotoToLoad photoToLoad;

PhotosLoader(PhotoToLoad photoToLoad) {

this.photoToLoad = photoToLoad;

}

@Override

public void run() {

if (imageViewReused(photoToLoad))

return;

Bitmap bmp = getBitmap(photoToLoad.url);

memoryCache.put(photoToLoad.url, bmp);

if (imageViewReused(photoToLoad))

return;

BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);

Activity a = (Activity) photoToLoad.imageView.getContext();

a.runOnUiThread(bd);

}

}

boolean imageViewReused(PhotoToLoad photoToLoad) {

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

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

return true;

return false;

}

/**

* 显示位图在UI线程

*

* @author Scorpio.Liu

*

*/

class BitmapDisplayer implements Runnable {

Bitmap bitmap;

PhotoToLoad photoToLoad;

public BitmapDisplayer(Bitmap b, PhotoToLoad p) {

bitmap = b;

photoToLoad = p;

}

public void run() {

if (imageViewReused(photoToLoad))

return;

if (bitmap != null) {

if (isSrc)

photoToLoad.imageView.setImageBitmap(bitmap);

else

photoToLoad.imageView.setBackgroundDrawable(new BitmapDrawable(bitmap));

} else {

if (isSrc)

photoToLoad.imageView.setImageResource(stub_id);

else

photoToLoad.imageView.setBackgroundResource(stub_id);

}

}

}

public void clearCache() {

memoryCache.clear();

fileCache.clear();

}

}

使用的时候用ImageLoader这个类就ok了,很方便~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。