日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

简单实现Android图片三级缓存机制

發布時間:2023/12/20 Android 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单实现Android图片三级缓存机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

????用戶在使用我們的APP時,通常會重復瀏覽一些圖片,這時如果每一次瀏覽都需要通過網絡獲取圖片,那么將會非常流量。為了節省用戶流量,提高圖片加載效率,我們通常使用圖片三級緩存策略,即通過網絡、本地、內存三級緩存圖片,來減少不必要的網絡交互,避免浪費流量。
????網上已經有很多講述圖片三級緩存的策略,這次我也來實現一次三級緩存,其中用到了LRU+SoftReference關于LRU算法,可以參考我之前的博客LinkedHashMap最佳實踐:LruCache。首先我將整個機制流程展示給大家:

下面是源碼實現:

/*** @ClassName: CastielImageLoader * @Description: LRU+SoftReference* @author 猴子搬來的救兵 http://blog.csdn.net/mynameishuangshuai*/ public class CastielImageLoader {private static final int MAX_CAPACITY = 20;// 鏈表長度private static Context mContext;// 獲取APP的緩存地址private static CastielImageLoader castielImageLoader;// 鍵是圖片地址、值是軟引用private static final LinkedHashMap<String, SoftReference<Bitmap>> firstCacheMap = new LinkedHashMap<String, SoftReference<Bitmap>>(MAX_CAPACITY) {protected boolean removeEldestEntry(java.util.Map.Entry<String, java.lang.ref.SoftReference<Bitmap>> eldest) {// 返回true表示移除最老的軟引用,保證內存平衡if (this.size() > MAX_CAPACITY) {return true;} else {// 否則往磁盤中添加diskCache(eldest.getKey(), eldest.getValue());return false;}}};/*** 單例模式加載CastielImageLoader* @return*/public static CastielImageLoader getInstance() {if (castielImageLoader == null) {castielImageLoader = new CastielImageLoader();}return castielImageLoader;}/*** 加載圖片到對應組件* * @param key 所需加載的路徑* @param view 被加載的組件* @param drawable 沒有加載前默認顯示圖片*/@SuppressWarnings("deprecation")public void loadImage(String key, ImageView view, Drawable drawable ,Context context) {mContext = context;synchronized (view) {// 檢查緩存中是否已有Bitmap bitmap = getFromCache(key);if (bitmap != null) {// 如果有了就從緩存中取出顯示view.setImageBitmap(bitmap);} else {// 軟應用緩存中不存在,磁盤中也不存在,只能下載// 下載之前應該先放一張默認圖,用來友好顯示view.setBackgroundDrawable(drawable);// 用異步任務去下載new CastielAsyncImageLoaderTask(view).execute(key);}}}/*** 判斷緩存中是否已經有了,如果有了就從緩存中取出* * @param key* @return*/private Bitmap getFromCache(String key) {// 檢查內存軟引中是否存在synchronized (firstCacheMap) {if (firstCacheMap.get(key) != null) {// 內存軟引用中有Bitmap bitmap = firstCacheMap.get(key).get();if (bitmap != null) {// 說明拿到了firstCacheMap.put(key, new SoftReference<Bitmap>(bitmap));return bitmap;}}}// 檢查磁盤中是否存在Bitmap bitmap = getFromLocalSD(key);if (bitmap != null) {// 硬盤中有firstCacheMap.put(key, new SoftReference<Bitmap>(bitmap));return bitmap;}return null;}/*** 判斷本地磁盤中是否已經有了該圖片,如果有了就從本地磁盤中取出* @param key* @return*/private Bitmap getFromLocalSD(String key) {String fileName = MD5Util.getMD5Str(key);if (fileName == null) {// 如果文件名為Null,直接返回nullreturn null;} else {String filePath = mContext.getCacheDir().getAbsolutePath() + File.separator + fileName;InputStream is = null;try {is = new FileInputStream(new File(filePath));Bitmap bitmap = BitmapFactory.decodeStream(is);return bitmap;} catch (FileNotFoundException e) {e.printStackTrace();} finally {try {is.close();} catch (IOException e) {e.printStackTrace();}}}return null;}/*** 把圖片緩存到本地磁盤,拿到圖片,寫到SD卡中* * @param key 圖片的URL* @param value Bitmap*/private static void diskCache(String key, SoftReference<Bitmap> value) {// 把寫入SD的圖片名字改為基于MD5加密算法加密后的名字String fileName = MD5Util.getMD5Str(key);String filePath = mContext.getCacheDir().getAbsolutePath() + File.separator + fileName;FileOutputStream os = null;try {os = new FileOutputStream(new File(filePath));if (value.get() != null) {value.get().compress(Bitmap.CompressFormat.JPEG, 60, os);}} catch (FileNotFoundException e) {e.printStackTrace();} finally {if (os != null) {try {os.close();} catch (IOException e) {e.printStackTrace();}}}}/*** * @ClassName: MyAsyncImageLoaderTask * @Description: 異步加載圖片 * @author */class CastielAsyncImageLoaderTask extends AsyncTask<String, Void, Bitmap>{private ImageView imageView;// 圖片組件private String key;//圖片路徑public CastielAsyncImageLoaderTask(ImageView imageView) {this.imageView = imageView;}@Overrideprotected Bitmap doInBackground(String... params) {this.key = params[0];// 圖片的路徑Bitmap bitmap = castielDownload(key);return bitmap;}@Overrideprotected void onPostExecute(Bitmap result) {super.onPostExecute(result);if (result != null) {// 說明已經下載下來了addFirstCache(key,result);imageView.setImageBitmap(result);// 加載網絡中的圖片}}}/*** 根據圖片路徑執行圖片下載* @param key* @return*/public Bitmap castielDownload(String key) {InputStream is = null;try {is = CastielHttpUtils.castielDownLoad(key);return BitmapFactory.decodeStream(is);// InputStream這種加載方式暫用內存最小} catch (IOException e) {e.printStackTrace();} finally {try {is.close();} catch (IOException e) {e.printStackTrace();}}return null;}/*** 添加到緩存中去* @param key* @param result*/public void addFirstCache(String key, Bitmap result) {if (result != null) {synchronized (firstCacheMap) {firstCacheMap.put(key, new SoftReference<Bitmap>(result));}}} }

網絡加載工具類 CastielHttpUtils.java

public class CastielHttpUtils {public static InputStream castielDownLoad(String key) throws IOException{HttpURLConnection conn = (HttpURLConnection) new URL(key).openConnection();return conn.getInputStream();} }

測試,調用我們的圖片緩存工具 MainActivity.java

public class MainActivity extends Activity {ImageView img;String imgURl = "http://img2.imgtn.bdimg.com/it/u=3722998253,3365379445&fm=21&gp=0.jpg";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);img = (ImageView) findViewById(R.id.img);CastielImageLoader.getInstance().loadImage(imgURl, img, this.getResources().getDrawable(R.drawable.ic_launcher),MainActivity.this);}}

布局文件 activity_main

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent" ><TextView android:id="@+id/tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="猴子搬來的救兵 http://blog.csdn.net/mynameishuangshuai" /><ImageView android:id="@+id/img"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/tv"android:layout_marginLeft="20dp"android:layout_marginTop="80dp"android:src="@drawable/tt" /></RelativeLayout>

測試加載圖片結果如下:

總結

以上是生活随笔為你收集整理的简单实现Android图片三级缓存机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。