引言
目前創(chuàng)新互聯(lián)建站已為上千余家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機(jī)、綿陽服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計(jì)、鳳縣網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
使用微信時(shí)我們會發(fā)現(xiàn),首次進(jìn)入微信的好友列表時(shí),會加載好友頭像,但是再次進(jìn)入時(shí),就不用重新加載了,而且其他頁面都不用重新加載,說明微信的好友頭像是緩存在本地的,然后好友修改頭像后,又會及時(shí)的更新,這個(gè)功能是如何實(shí)現(xiàn)的呢,我們來分析一下
分析
關(guān)于頭像緩存的實(shí)現(xiàn)
頭像是網(wǎng)絡(luò)圖片,而且數(shù)據(jù)量較大,如果用我們常用的SharedPreferences將頭像以Bitmap的形式存儲,勢必會造成OOM,這個(gè)方法是行不通的,我們存儲的只能是圖片的地址,但是如果只存儲地址的話,要轉(zhuǎn)化成圖片,還是要通過網(wǎng)絡(luò)請求重新加載,達(dá)不到我們要求的效果,所以我們需要在磁盤中單獨(dú)開辟一塊空間,將頭像以Bitmap的形式進(jìn)行存儲,如何實(shí)現(xiàn)呢?其實(shí)關(guān)于網(wǎng)絡(luò)圖片的緩存,有很多開源的第三方框架,比較可靠好用的如xUtils,Glide,volley,Universal-Image-Loader,Picasso,Fresco等等。
下面我們以常用的xUtils為例首先對BitmapUtils的實(shí)例化,對于磁盤緩存路徑,磁盤緩存空間大小,內(nèi)存緩存的空間大小,內(nèi)存緩存百分比可以自定義,也可以使用默認(rèn)配置,代碼如下:
/** * @param context 上下文 */ public BitmapUtils(Context context) { this(context, null); } /** * @param context 上下文 * @param diskCachePath 磁盤高速緩存路徑 */ public BitmapUtils(Context context, String diskCachePath) { if (context == null) { throw new IllegalArgumentException("context may not be null"); } this.context = context.getApplicationContext(); globalConfig = BitmapGlobalConfig.getInstance(this.context, diskCachePath); defaultDisplayConfig = new BitmapDisplayConfig(); } /** * * @param context 上下文 * @param diskCachePath 磁盤高速緩存路徑 * @param memoryCacheSize 內(nèi)存緩存空間大小 */ public BitmapUtils(Context context, String diskCachePath, int memoryCacheSize) { this(context, diskCachePath); globalConfig.setMemoryCacheSize(memoryCacheSize); } /** * * @param context 上下文 * @param diskCachePath 磁盤高速緩存路徑 * @param memoryCacheSize 內(nèi)存緩存空間大小 * @param diskCacheSize 磁盤高速緩存空間大小 */ public BitmapUtils(Context context, String diskCachePath, int memoryCacheSize, int diskCacheSize) { this(context, diskCachePath); globalConfig.setMemoryCacheSize(memoryCacheSize); globalConfig.setDiskCacheSize(diskCacheSize); } /** * * @param context 上下文 * @param diskCachePath 磁盤高速緩存路徑 * @param memoryCachePercent 內(nèi)存緩存百分比 */ public BitmapUtils(Context context, String diskCachePath, float memoryCachePercent) { this(context, diskCachePath); globalConfig.setMemCacheSizePercent(memoryCachePercent); } /** * * @param context 上下文 * @param diskCachePath 磁盤高速緩存路徑 * @param memoryCachePercent 內(nèi)存緩存百分比 * @param diskCacheSize 磁盤緩存空間大小 */ public BitmapUtils(Context context, String diskCachePath, float memoryCachePercent, int diskCacheSize) { this(context, diskCachePath); globalConfig.setMemCacheSizePercent(memoryCachePercent); globalConfig.setDiskCacheSize(diskCacheSize); }
一般情況下,我們只需要使用默認(rèn)配置就可以了,即
BitmapUtils bitmap = new BitmapUtils(context);
然后對圖片的緩存和顯示
/** * 根據(jù)圖片路徑,顯示到具體的View上 * @param container 要把圖片顯示到的View * @param uri 圖片路徑 */ public <T extends View> void display(T container, String uri) { display(container, uri, null, null); } /** * 根據(jù)圖片路徑,顯示到具體的View上 * @param container 要把圖片顯示到的View * @param uri 圖片路徑 * @param displayConfig */ public <T extends View> void display(T container, String uri, BitmapDisplayConfig displayConfig) { display(container, uri, displayConfig, null); } /** * 根據(jù)圖片路徑,顯示到具體的View上 * @param container 要把圖片顯示到的View * @param uri 圖片路徑 * @param callBack 加載過程回調(diào)各種狀態(tài) */ public <T extends View> void display(T container, String uri, BitmapLoadCallBack<T> callBack) { display(container, uri, null, callBack); } /** * 根據(jù)圖片路徑,顯示到具體的View上 * @param container 要把圖片顯示到的View * @param uri 圖片路徑 * @param displayConfig 位圖顯示配置 * @param callBack */ public <T extends View> void display(T container, String uri, BitmapDisplayConfig displayConfig, BitmapLoadCallBack<T> callBack) { if (container == null) { return; } if (callBack == null) { callBack = new DefaultBitmapLoadCallBack<T>(); } if (displayConfig == null || displayConfig == defaultDisplayConfig) { displayConfig = defaultDisplayConfig.cloneNew(); } // Optimize Max BitmapSize size = displayConfig.getBitmapMaxSize();SizedisplayConfig.setBitmapMaxSize(BitmapCommonUtils.optimizeMaxSizeByView(container, size.getWidth(), size.getHeight())); container.clearAnimation(); if (TextUtils.isEmpty(uri)) { callBack.onLoadFailed(container, uri, displayConfig.getLoadFailedDrawable()); return; } // start loading callBack.onPreLoad(container, uri, displayConfig); // find bitmap from mem cache. Bitmap bitmap = globalConfig.getBitmapCache().getBitmapFromMemCache(uri, displayConfig); if (bitmap != null) { callBack.onLoadStarted(container, uri, displayConfig); callBack.onLoadCompleted( container, uri, bitmap, displayConfig, BitmapLoadFrom.MEMORY_CACHE); } else if (!bitmapLoadTaskExist(container, uri, callBack)) { final BitmapLoadTask<T> loadTask = new BitmapLoadTask<T>(container, uri, displayConfig, callBack); // get executor PriorityExecutor executor = globalConfig.getBitmapLoadExecutor(); File diskCacheFile = this.getBitmapFileFromDiskCache(uri); boolean diskCacheExist = diskCacheFile != null && diskCacheFile.exists(); if (diskCacheExist && executor.isBusy()) { executor = globalConfig.getDiskCacheExecutor(); } // set loading image Drawable loadingDrawable = displayConfig.getLoadingDrawable(); callBack.setDrawable(container, new AsyncDrawable<T>(loadingDrawable, loadTask)); loadTask.setPriority(displayConfig.getPriority()); loadTask.executeOnExecutor(executor); } }
從這段代碼中我們可以看到,當(dāng)要加載某張圖片時(shí),會根據(jù)圖片地址進(jìn)行查找是否有對應(yīng)的bitmap緩存圖片,如果有就直接引用緩存,如果沒有就加載并緩存,所以我們對圖片的緩存只需要實(shí)現(xiàn)以上方法就可以了,而且只要設(shè)置相同的緩存路徑,就可以實(shí)現(xiàn)一個(gè)頁面緩存后,其他頁面有相同圖片也可以調(diào)用。那么緩存之后,好友更新頭像,又是怎么做到即時(shí)更新的呢?
緩存后如何實(shí)現(xiàn)即時(shí)更新頭像
根據(jù)查閱的資料,可以歸結(jié)為以下幾種實(shí)現(xiàn)方式:
1.在服務(wù)器返回用戶數(shù)組時(shí)多加一個(gè)字段頭像最后一次修改時(shí)間或者修改過幾次等標(biāo)志符,與緩存進(jìn)行比較,是否有變化
2.利用圖片的checkSum來實(shí)現(xiàn),如果check到這個(gè)數(shù)字有變化,就會自動去更新
3.利用socket監(jiān)聽,當(dāng)好友頭像更新時(shí)候首先會告訴服務(wù)器,服務(wù)器將變化通知推送到所有好友,好友監(jiān)聽收到通知后自動更新
第一種方法和第二種方法本質(zhì)是一致的,通過請求服務(wù)器的數(shù)據(jù)與本地緩存進(jìn)行對比,是由客戶端處理的,第三種方法的話你換一次頭像就要服務(wù)器去提醒你的所有好友一遍,服務(wù)器壓力會不會比較大
仔細(xì)去研究一下微信,就會發(fā)現(xiàn),當(dāng)好友頭像修改后,如果你停留在某個(gè)頁面,進(jìn)入的這個(gè)頁面是之前進(jìn)入過的,還沒有銷毀,頭像是不會改變的,你需要打開一個(gè)新的頁面或者重新進(jìn)入微信,才會更新頭像,由此看出,微信并不是用的第三種方式,而是采用了前兩種方式的實(shí)現(xiàn)原理,只有在創(chuàng)建一個(gè)Activity或fragment時(shí),調(diào)用接口,讀取服務(wù)器數(shù)據(jù)時(shí)才會更新頭像
總結(jié)
通過以上的分析,我們基本捋清了思路,要實(shí)現(xiàn)類似微信的緩存和更新還有頭像,先是在磁盤開辟一個(gè)空間,用于讀寫頭像的Bitmap,然后創(chuàng)建頁面時(shí),讀取服務(wù)器數(shù)據(jù)和本地緩存進(jìn)行比較,如果有變化就進(jìn)行更新
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
網(wǎng)頁題目:android實(shí)現(xiàn)類似微信緩存和即時(shí)更新好友頭像示例
當(dāng)前地址:http://bm7419.com/article36/ipoepg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、網(wǎng)站策劃、自適應(yīng)網(wǎng)站、域名注冊、靜態(tài)網(wǎng)站、ChatGPT
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)