国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Android - android中圖片的三級緩存cache策略(內存/文件/網絡)

android中圖片的三級緩存cache策略(內存/文件/網絡)

2021-01-25 15:16Android開發網 Android

實現圖片緩存也不難,需要有相應的cache策略。這里我采用 內存-文件-網絡 三層cache機制,其中內存緩存包括強引用緩存和軟引用緩存(SoftReference),其實網絡不算cache,這里姑且也把它劃到緩存的層次結構中

1.簡介
現在android應用中不可避免的要使用圖片,有些圖片是可以變化的,需要每次啟動時從網絡拉取,這種場景在有廣告位的應用以及純圖片應用(比如百度美拍)中比較多。

現在有一個問題:假如每次啟動的時候都從網絡拉取圖片的話,勢必會消耗很多流量。在當前的狀況下,對于非wifi用戶來說,流量還是很貴的,一個很耗流量的應用,其用戶數量級肯定要受到影響。當然,我想,向百度美拍這樣的應用,必然也有其內部的圖片緩存策略。總之,圖片緩存是很重要而且是必須的。

2.圖片緩存的原理
實現圖片緩存也不難,需要有相應的cache策略。這里我采用 內存-文件-網絡 三層cache機制,其中內存緩存包括強引用緩存和軟引用緩存(SoftReference),其實網絡不算cache,這里姑且也把它劃到緩存的層次結構中。當根據url向網絡拉取圖片的時候,先從內存中找,如果內存中沒有,再從緩存文件中查找,如果緩存文件中也沒有,再從網絡上通過http請求拉取圖片。在鍵值對(key-value)中,這個圖片緩存的key是圖片url的hash值,value就是bitmap。所以,按照這個邏輯,只要一個url被下載過,其圖片就被緩存起來了。

關于Java中對象的軟引用(SoftReference),如果一個對象具有軟引用,內存空間足夠,垃 圾回收器就不會回收它;如果內存空間不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。軟引用可用來實現內存敏感的高 速緩存。使用軟引用能防止內存泄露,增強程序的健壯性。

從代碼上來說,采用一個ImageManager來負責圖片的管理和緩存,函數接口為public void loadBitmap(String url, Handler handler) ;其中url為要下載的圖片地址,handler為圖片下載成功后的回調,在handler中處理message,而message中包含了圖片的信息以及bitmap對象。ImageManager中使用的ImageMemoryCache(內存緩存)、ImageFileCache(文件緩存)以及LruCache(最近最久未使用緩存)會在后續文章中介紹。

3.代碼ImageManager.java

復制代碼 代碼如下:


/*
* 圖片管理
* 異步獲取圖片,直接調用loadImage()函數,該函數自己判斷是從緩存還是網絡加載
* 同步獲取圖片,直接調用getBitmap()函數,該函數自己判斷是從緩存還是網絡加載
* 僅從本地獲取圖片,調用getBitmapFromNative()
* 僅從網絡加載圖片,調用getBitmapFromHttp()
*
*/
public class ImageManager implements IManager
{
private final static String TAG = "ImageManager";

private ImageMemoryCache imageMemoryCache; //內存緩存

private ImageFileCache imageFileCache; //文件緩存

//正在下載的image列表
public static HashMap<String, Handler> ongoingTaskMap = new HashMap<String, Handler>();

//等待下載的image列表
public static HashMap<String, Handler> waitingTaskMap = new HashMap<String, Handler>();

//同時下載圖片的線程個數
final static int MAX_DOWNLOAD_IMAGE_THREAD = 4;

private final Handler downloadStatusHandler = new Handler(){
public void handleMessage(Message msg)
{
startDownloadNext();
}
};

public ImageManager()
{
imageMemoryCache = new ImageMemoryCache();
imageFileCache = new ImageFileCache();
}

/**
* 獲取圖片,多線程的入口
*/
public void loadBitmap(String url, Handler handler)
{
//先從內存緩存中獲取,取到直接加載
Bitmap bitmap = getBitmapFromNative(url);
if (bitmap != null)
{
Logger.d(TAG, "loadBitmap:loaded from native");
Message msg = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("url", url);
msg.obj = bitmap;
msg.setData(bundle);
handler.sendMessage(msg);
}
else
{
Logger.d(TAG, "loadBitmap:will load by network");
downloadBmpOnNewThread(url, handler);
}
}
/**
* 新起線程下載圖片
*/
private void downloadBmpOnNewThread(final String url, final Handler handler)
{
Logger.d(TAG, "ongoingTaskMap'size=" + ongoingTaskMap.size());

if (ongoingTaskMap.size() >= MAX_DOWNLOAD_IMAGE_THREAD)
{
synchronized (waitingTaskMap)
{
waitingTaskMap.put(url, handler);
}
}
else
{
synchronized (ongoingTaskMap)
{
ongoingTaskMap.put(url, handler);
}
new Thread()
{
public void run()
{
Bitmap bmp = getBitmapFromHttp(url);
// 不論下載是否成功,都從下載隊列中移除,再由業務邏輯判斷是否重新下載
// 下載圖片使用了httpClientRequest,本身已經帶了重連機制
synchronized (ongoingTaskMap)
{
ongoingTaskMap.remove(url);
}

if(downloadStatusHandler != null)
{
downloadStatusHandler.sendEmptyMessage(0);

}
Message msg = Message.obtain();
msg.obj = bmp;
Bundle bundle = new Bundle();
bundle.putString("url", url);
msg.setData(bundle);

if(handler != null)
{
handler.sendMessage(msg);
}
}
}.start();
}
}
/**
* 依次從內存,緩存文件,網絡上加載單個bitmap,不考慮線程的問題
*/
public Bitmap getBitmap(String url)
{
// 從內存緩存中獲取圖片
Bitmap bitmap = imageMemoryCache.getBitmapFromMemory(url);
if (bitmap == null)
{
// 文件緩存中獲取
bitmap = imageFileCache.getImageFromFile(url);
if (bitmap != null)
{
// 添加到內存緩存
imageMemoryCache.addBitmapToMemory(url, bitmap);
}
else
{
// 從網絡獲取
bitmap = getBitmapFromHttp(url);
}
}
return bitmap;
}

/**
* 從內存或者緩存文件中獲取bitmap
*/
public Bitmap getBitmapFromNative(String url)
{
Bitmap bitmap = null;
bitmap = imageMemoryCache.getBitmapFromMemory(url);

if(bitmap == null)
{
bitmap = imageFileCache.getImageFromFile(url);
if(bitmap != null)
{
// 添加到內存緩存
imageMemoryCache.addBitmapToMemory(url, bitmap);
}
}
return bitmap;
}

/**
* 通過網絡下載圖片,與線程無關
*/
public Bitmap getBitmapFromHttp(String url)
{
Bitmap bmp = null;

try
{
byte[] tmpPicByte = getImageBytes(url);

if (tmpPicByte != null)
{
bmp = BitmapFactory.decodeByteArray(tmpPicByte, 0,
tmpPicByte.length);
}
tmpPicByte = null;
}
catch(Exception e)
{
e.printStackTrace();
}

if(bmp != null)
{
// 添加到文件緩存
imageFileCache.saveBitmapToFile(bmp, url);
// 添加到內存緩存
imageMemoryCache.addBitmapToMemory(url, bmp);
}
return bmp;
}

/**
* 下載鏈接的圖片資源
*
* @param url
*
* @return 圖片
*/
public byte[] getImageBytes(String url)
{
byte[] pic = null;
if (url != null && !"".equals(url))
{
Requester request = RequesterFactory.getRequester(
Requester.REQUEST_REMOTE, RequesterFactory.IMPL_HC);
// 執行請求
MyResponse myResponse = null;
MyRequest mMyRequest;
mMyRequest = new MyRequest();
mMyRequest.setUrl(url);
mMyRequest.addHeader(HttpHeader.REQ.ACCEPT_ENCODING, "identity");
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
myResponse = request.execute(mMyRequest);
is = myResponse.getInputStream().getImpl();
baos = new ByteArrayOutputStream();
byte[] b = new byte[512];
int len = 0;
while ((len = is.read(b)) != -1)
{
baos.write(b, 0, len);
baos.flush();
}
pic = baos.toByteArray();
Logger.d(TAG, "icon bytes.length=" + pic.length);
}
catch (Exception e3)
{
e3.printStackTrace();
try
{
Logger.e(TAG,
"download shortcut icon faild and responsecode="
+ myResponse.getStatusCode());
}
catch (Exception e4)
{
e4.printStackTrace();
}
}
finally
{
try
{
if (is != null)
{
is.close();
is = null;
}
}
catch (Exception e2)
{
e2.printStackTrace();
}
try
{
if (baos != null)
{
baos.close();
baos = null;
}
}
catch (Exception e2)
{
e2.printStackTrace();
}
try
{
request.close();
}
catch (Exception e1)
{
e1.printStackTrace();
}
}
}
return pic;
}

/**
* 取出等待隊列第一個任務,開始下載
*/
private void startDownloadNext()
{
synchronized(waitingTaskMap)
{
Logger.d(TAG, "begin start next");
Iterator iter = waitingTaskMap.entrySet().iterator();

while (iter.hasNext())
{

Map.Entry entry = (Map.Entry) iter.next();
Logger.d(TAG, "WaitingTaskMap isn't null,url=" + (String)entry.getKey());

if(entry != null)
{
waitingTaskMap.remove(entry.getKey());
downloadBmpOnNewThread((String)entry.getKey(), (Handler)entry.getValue());
}
break;
}
}
}

public String startDownloadNext_ForUnitTest()
{
String urlString = null;
synchronized(waitingTaskMap)
{
Logger.d(TAG, "begin start next");
Iterator iter = waitingTaskMap.entrySet().iterator();

while (iter.hasNext())
{
Map.Entry entry = (Map.Entry) iter.next();
urlString = (String)entry.getKey();
waitingTaskMap.remove(entry.getKey());
break;
}
}
return urlString;
}

/**
* 圖片變為圓角
* @param bitmap:傳入的bitmap
* @param pixels:圓角的度數,值越大,圓角越大
* @return bitmap:加入圓角的bitmap
*/
public static Bitmap toRoundCorner(Bitmap bitmap, int pixels)
{
if(bitmap == null)
return null;
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}

public byte managerId()
{
return IMAGE_ID;
}
}

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 天天摸天天操 | 成人亚洲精品 | 男女免费观看在线爽爽爽视频 | 亚洲欧美成人a毛片 | 最新国产在线 | 欧美日韩一区二 | 精品视频免费 | 女人高潮视频网站 | 操操av| 国产精品久久久久久久久久久久久 | 中文字幕亚洲专区 | 亚洲自拍偷拍综合 | 成人av在线播放 | 中文字幕在线电影观看 | 激情久久免费视频 | 国产欧美日韩在线观看 | 欧美 日韩 中文 | 亚洲综合社区 | 超碰97国产精品人人cao | 黄a在线观看 | 久久69精品久久久久久久电影好 | 日韩在线观看一区 | 一区二区日韩精品 | 国产免费性 | 午夜国产 | 99久久99久久久精品色圆 | 久久精品xx老女人老配少 | 亚洲欧美日韩国产 | 午夜成人在线视频 | 久草电影网 | 国产精品久久国产精品 | 一区二区三区久久 | 久久久国产一区二区三区 | 亚洲欧美激情精品一区二区 | 精品96久久久久久中文字幕无 | 草草浮力影院 | 中文字幕在线播放一区 | 俺来也俺也啪www色 性色视频在线 | 欧美黄色成人 | 成人a在线视频免费观看 | 欧美成人a |