Android開發之一種簡單的非同步載入圖片方法

來源:互聯網
上載者:User

標籤:android圖片非同步載入方法

首先說明的是,該方法已經被我拋棄了。之前用它,發現載入速度不好。具體沒怎麼細心的看。

現在我用volley了。拿出來只是給大家批判的。

package com.souya.seller.util.ex;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import java.lang.ref.SoftReference;import java.util.HashMap;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;import AXLib.Utility.Console;import AXLib.Utility.HttpClient;import AXLib.Utility.Queue;import AXLib.Utility.RuntimeExceptionEx;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.media.ThumbnailUtils;import android.net.Uri;import android.os.Handler;import android.os.Message;import android.provider.MediaStore.Video.Thumbnails;import android.util.Log;import android.widget.ImageView;import com.souya.seller.app.SellerApplication;public class AsyncImageLoader {private static boolean _D =  false;//AppConfig._D &&private static final String TAG = "AsyncImageLoader";public static String CachePath = null;private static String ThumbnailPath = null;private static boolean _isInit = false;private static Context _ctx;private static Bitmap _empty = Bitmap.createBitmap(1, 1, Bitmap.Config.RGB_565);private static HashMap<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();private static Queue<Runnable> queue = new Queue<Runnable>();// 線程池:最大50條,每次執行:1條,空閑線程結束的逾時時間:180秒private static ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 20, 300, TimeUnit.SECONDS, queue);public final static AsyncImageLoader Instance = new AsyncImageLoader();public static void Init(final Context context) {CachePath = SellerApplication.getInstance().mAppCacheDir + "";ThumbnailPath = CachePath + "/thumbnails";if (!new File(ThumbnailPath).exists())new File(ThumbnailPath).mkdirs();_ctx = context;_isInit = true;}public static Drawable loadDrawable(final Context context, final String url, final ImageCallback imageCallback) {if (!_isInit)Init(context);final String key = url;synchronized (imageCache) {if (imageCache.containsKey(key)) {SoftReference<Bitmap> softReference = imageCache.get(key);Bitmap bmp = softReference.get();if (bmp != null && !bmp.isRecycled()) {if (bmp == _empty) {bmp = bmp;} elsereturn new BitmapDrawable(bmp);}} else {imageCache.put(key, new SoftReference<Bitmap>(_empty));}}final Handler handler = new Handler() {public void handleMessage(Message message) {imageCallback.imageLoaded((Drawable) message.obj, url);}};// 用線程池來做下載圖片的任務executor.execute(new Runnable() {@Overridepublic void run() {Bitmap bmp = loadImage(url);if (bmp != null) {synchronized (imageCache) {if (imageCache.containsKey(key)) {imageCache.put(key, new SoftReference<Bitmap>(bmp));Message message = handler.obtainMessage(0, new BitmapDrawable(bmp));handler.sendMessage(message);} else {if (!bmp.isRecycled())bmp.recycle();bmp = null;System.gc();}}}}});return null;}public static Drawable loadDrawable(final Context context, final String url, final int width, final int height, final ImageCallback imageCallback) {if (!_isInit)Init(context);final String key = String.format("%s_%d_%d", url, width, height);if (imageCache.containsKey(key)) {SoftReference<Bitmap> softReference = imageCache.get(key);Bitmap bmp = softReference.get();if (bmp != null && !bmp.isRecycled()) {if (bmp == _empty) {bmp = bmp;} elsereturn new BitmapDrawable(bmp);}} else {imageCache.put(key, new SoftReference<Bitmap>(_empty));}final Handler handler = new Handler() {public void handleMessage(Message message) {imageCallback.imageLoaded((Drawable) message.obj, url);}};// 用線程池來做下載圖片的任務executor.execute(new Runnable() {@Overridepublic void run() {Bitmap bmp = loadImageAndScale(url, width, height);if (imageCache.containsKey(key)) {imageCache.put(key, new SoftReference<Bitmap>(bmp));Message message = handler.obtainMessage(0, new BitmapDrawable(bmp));handler.sendMessage(message);} else {if (!bmp.isRecycled())bmp.recycle();bmp = null;System.gc();}}});return null;} public static void releaseDrawable(String url, int width, int height) {log("releaseDrawable" + url);String key = String.format("%s_%d_%d", url, width, height);releaseDrawable(key);}public static void releaseDrawable(String url) {try {log("releaseDrawable" + url);String key = url;synchronized (imageCache) {if (imageCache.containsKey(key)) {SoftReference<Bitmap> softReference = imageCache.get(key);imageCache.remove(key);Bitmap bmp = softReference.get();if (bmp != null && bmp != _empty && !bmp.isRecycled()) {bmp.recycle();bmp = null;}System.gc();}}} catch (Exception e) {String stack = RuntimeExceptionEx.GetStackTraceString(e);}}private static HashMap<String, Object> _loadImageLocks = new HashMap<String, Object>();public static Bitmap loadImage(String url) {log("londImage:" + url);Object lockObj = null;synchronized (_loadImageLocks) {if (_loadImageLocks.containsKey(url))lockObj = _loadImageLocks.get(url);else {lockObj = new Object();_loadImageLocks.put(url, lockObj);}}synchronized (lockObj) {if (isLocalImage(url))return loadLocalImage(url);else {String localUrl = getCacheFileName(url);Bitmap bmp = null;if (new File(localUrl).exists())bmp = loadLocalImage(localUrl);try {if (bmp == null)bmp = loadHttpImage(url, 0, 0);} catch (Throwable e) {if (_D)throw RuntimeExceptionEx.Create(e);}return bmp;}}}public static Bitmap loadImage(String url, int width, int height) {log("londImage:" + url);Object lockObj = null;synchronized (_loadImageLocks) {if (_loadImageLocks.containsKey(url))lockObj = _loadImageLocks.get(url);else {lockObj = new Object();_loadImageLocks.put(url, lockObj);}}synchronized (lockObj) {if (isLocalImage(url))return loadLocalImage(url, width, height);else {String localUrl = getCacheFileName(url);Bitmap bmp = null;if (new File(localUrl).exists())bmp = loadLocalImage(localUrl, width, height);try {if (bmp == null)bmp = loadHttpImage(url, width, height);} catch (Throwable e) {if (_D)throw RuntimeExceptionEx.Create(e);}return bmp;}}}private static Bitmap loadLocalImageByVideo(String url) {log("loadLocalImageByVideo:" + url);if (!new File(url).exists())return null;Bitmap bmp = ThumbnailUtils.createVideoThumbnail(url, Thumbnails.MINI_KIND);return bmp;}private static Bitmap loadLocalImage(String url) {return loadLocalImage(url, 0);}private static Bitmap loadLocalImage(String url, int width, int height) {if (width == 0 && height == 0)return loadLocalImage(url);elsereturn _loadLocalImage(url, width, height);}private static Bitmap _loadLocalImage(String url, int width, int height) {try {if (!new File(url).exists())return null;// 擷取螢幕的寬和高/** * 為了計算縮放的比例,我們需要擷取整個圖片的尺寸,而不是圖片 * BitmapFactory.Options類中有一個布爾型變數inJustDecodeBounds,將其設定為true * 這樣,我們擷取到的就是圖片的尺寸,而不用載入圖片了。 當我們設定這個值的時候,我們接著就可以從BitmapFactory. * Options的outWidth和outHeight中擷取到值 */BitmapFactory.Options op = new BitmapFactory.Options();op.inJustDecodeBounds = true;Uri uri = Uri.fromFile(new File(url));// 由於使用了MediaStore儲存,這雷根據URI擷取輸入資料流的形式Bitmap pic = BitmapFactory.decodeStream(_ctx.getContentResolver().openInputStream(uri), null, op);int wRatio = (int) Math.ceil(op.outWidth / (float) width); // 計算寬度比例int hRatio = (int) Math.ceil(op.outHeight / (float) height); // 計算高度比例if (pic != null && !pic.isRecycled())pic.recycle();/** * 接下來,我們就需要判斷是否需要縮放以及到底對寬還是高進行縮放。 如果高和寬不是全都超出了螢幕,那麼無需縮放。 * 如果高和寬都超出了螢幕大小,則如何選擇縮放呢》 這需要判斷wRatio和hRatio的大小 * 大的一個將被縮放,因為縮放大的時,小的應該自動進行同比率縮放。 縮放使用的還是inSampleSize變數 */if (wRatio > 1 && hRatio > 1) {if (wRatio > hRatio) {op.inSampleSize = wRatio;} else {op.inSampleSize = hRatio;}}op.inJustDecodeBounds = false; // 注意這裡,一定要設定為false,因為上面我們將其設定為true來擷取圖片尺寸了try {pic = BitmapFactory.decodeStream(_ctx.getContentResolver().openInputStream(uri), null, op);} catch (OutOfMemoryError e) {loadLocalImage(url, 1);}return pic;} catch (Throwable e) {throw RuntimeExceptionEx.Create(e);}}private static Bitmap loadLocalImage(String url, int inSampleSize) {log("loadLocalImage:" + url);if (!new File(url).exists())return null;if (url.endsWith(".mp4") || url.endsWith(".3gp")) {return loadLocalImageByVideo(url);}BitmapFactory.Options opt = new BitmapFactory.Options();// opt.inPreferredConfig = Bitmap.Config.RGB_565;// opt.inPurgeable = true;// opt.inInputShareable = true;opt.inSampleSize = inSampleSize;// 擷取資源圖片InputStream is = null;try {is = new FileInputStream(url);if (is != null) {Bitmap map = BitmapFactory.decodeStream(is, null, opt);if (map == null)return null;int height = map.getHeight();int width = map.getWidth();if (width > 1920 || height > 1080) {if (inSampleSize == 0)inSampleSize = 2;elseinSampleSize++;if (is != null) {try {is.close();} catch (Exception ex) {}}map.recycle();map = null;return loadLocalImage(url, inSampleSize);} else {return map;}}} catch (OutOfMemoryError e) {if (is != null) {try {is.close();} catch (Exception ex) {}}System.gc();if (inSampleSize < 50) {if (inSampleSize == 0)inSampleSize = 2;elseinSampleSize++;return loadLocalImage(url, inSampleSize);} elsereturn null;} catch (Throwable e) {String stack = RuntimeExceptionEx.GetStackTraceString(e);//CLLog.Error(e);//if (_D)    //throw RuntimeExceptionEx.Create(e);} finally {if (is != null) {try {is.close();} catch (Exception e) {}}System.gc();}return null;}private static Bitmap loadHttpImage(String url, int width, int height) {log("loadHttpImage:" + url);String localUrl = getCacheFileName(url);try {HttpClient hc = new HttpClient();if (hc.downFile(url, localUrl))return loadLocalImage(localUrl, width, height);elsereturn null;} catch (Exception e) {String stack = RuntimeExceptionEx.GetStackTraceString(e);//CLLog.Error(e);//if (_D)//throw RuntimeExceptionEx.Create(e);}return null;}public static Bitmap loadImageAndScale(String url, int width, int height) {log("loadImageAndScale:" + url);String thumbnailUrl = getThumbnailFileName(url, width, height);Bitmap bmp = loadLocalImage(url, width, height);if (bmp == null) {try {bmp = loadImage(url, width, height);} catch (Exception e) {String stack = RuntimeExceptionEx.GetStackTraceString(e);}if (bmp != null) {Bitmap bmpThumbnail = ImageHelper.ScaleAndSave(bmp, thumbnailUrl, width, height, true, true);if (bmpThumbnail != bmp && !bmp.isRecycled())bmp.recycle();bmp = null;System.gc();bmp = bmpThumbnail;}}return bmp;}private static boolean isLocalImage(String url) {return new File(url).exists();}private static String getCacheFileName(String url) {if (isLocalImage(url))return url;String localUrl = null;if (url != null && url.length() != 0) {localUrl = CachePath + "/" + url.substring(url.lastIndexOf("/") + 1);}return localUrl;}private static String getThumbnailFileName(String url, int width, int height) {String thumbnailUrl = null;if (url != null && url.length() != 0) {thumbnailUrl = String.format("%s/%d_%d_%s", ThumbnailPath, width, height, url.substring(url.lastIndexOf("/") + 1));}return thumbnailUrl;}private static void log(String msg) {// Console.d("AsyncImageLoader", msg);}public interface ImageCallback {public void imageLoaded(Drawable imageDrawable, String imageUrl);}}


Android開發之一種簡單的非同步載入圖片方法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.