在androID应用开发的时候,加载网络图片是一个非常重要的部分,很多图片不可能放在本地,所以就必须要从服务器或者网络读取图片。
软引用是一个现在非常流行的方法,用户体验比较好,不用每次都需要从网络下载图片,如果下载后就存到本地,下次读取时首先查看本地有没有,如果没有再从网络读取。
下面就分享一下异步加载网络图片的方法吧。
fileCache.java
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
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 java.net.httpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.net.URLEncoder; import java.util.Map; /*** http 请求工具类* * @author Scorpio.liu* */ public class httpUtil { /** * 获取响应字符串 * * @param path * 路径 * @param parameters * 参数 * @return 响应字符串 */ public static String getResponseStr(String path,Map<String,String> parameters) { StringBuffer buffer = new StringBuffer(); URL url; try { if (parameters != null && !parameters.isEmpty()) { for (Map.Entry<String,String> 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,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,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,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,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
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<String,SoftReference<Bitmap>> cache = Collections .synchronizedMap(new HashMap<String,SoftReference<Bitmap>>());// 软引用 public Bitmap get(String ID) { if (!cache.containsKey(ID)) return null; SoftReference<Bitmap> ref = cache.get(ID); return ref.get(); } public voID put(String ID,Bitmap bitmap) { cache.put(ID,new SoftReference<Bitmap>(bitmap)); } public voID clear() { cache.clear(); } }
ImageLoader.java
import java.io.file; import java.io.fileinputStream; import java.io.fileNotFoundException; import java.io.UnsupportedEnCodingException; import java.net.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<ImageVIEw,String> imageVIEws = Collections .synchronizedMap(new WeakHashMap<ImageVIEw,String>()); 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),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了,很方便~
希望本文所述对大家学习AndroID软件编程有所帮助。
总结以上是内存溢出为你收集整理的Android实现图片异步加载并缓存到本地全部内容,希望文章能够帮你解决Android实现图片异步加载并缓存到本地所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)