招生熱線
0755-86191118 0755-86191118
我的位置: 首頁 > 學習專區 > 安卓技術 > Android 異步加載網絡圖片并緩存到本地

Android 異步加載網絡圖片并緩存到本地

2014-08-19 14:21:12
來源:
[導讀]   在android應用開發的時候,加載網絡圖片是一個非常重要的部分,很多圖片不可能放在本地,所以就必須要從服務器或者網絡讀取圖片。  

  在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 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 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 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 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了,很方便~

評論
相關文章
好吊妞免费视频在线观看,久久亚洲国产人成综合网,久久精品国产2020,欧美精品综合在线
午夜福利在线91 | 五月天天堂AV在线播放 | 亚洲欧美日韩在线综合久 | 亚另类在线观看 | 综合亚洲日本日日摸夜夜添 | 在线观看亚洲人成电影 |