最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

android 實(shí)現(xiàn)類似微信緩存和即時(shí)更新好友頭像示例

 更新時(shí)間:2017年01月22日 11:59:14   作者:jindong  
本篇文章主要介紹了android 實(shí)現(xiàn)類似微信緩存和即時(shí)更新好友頭像示例,具有一定的參考價(jià)值,有興趣的可以了解一下。

引言

使用微信時(shí)我們會(huì)發(fā)現(xiàn),首次進(jìn)入微信的好友列表時(shí),會(huì)加載好友頭像,但是再次進(jìn)入時(shí),就不用重新加載了,而且其他頁面都不用重新加載,說明微信的好友頭像是緩存在本地的,然后好友修改頭像后,又會(huì)及時(shí)的更新,這個(gè)功能是如何實(shí)現(xiàn)的呢,我們來分析一下

分析

關(guān)于頭像緩存的實(shí)現(xiàn)

頭像是網(wǎng)絡(luò)圖片,而且數(shù)據(jù)量較大,如果用我們常用的SharedPreferences將頭像以Bitmap的形式存儲(chǔ),勢(shì)必會(huì)造成OOM,這個(gè)方法是行不通的,我們存儲(chǔ)的只能是圖片的地址,但是如果只存儲(chǔ)地址的話,要轉(zhuǎn)化成圖片,還是要通過網(wǎng)絡(luò)請(qǐng)求重新加載,達(dá)不到我們要求的效果,所以我們需要在磁盤中單獨(dú)開辟一塊空間,將頭像以Bitmap的形式進(jìn)行存儲(chǔ),如何實(shí)現(xiàn)呢?其實(shí)關(guān)于網(wǎng)絡(luò)圖片的緩存,有很多開源的第三方框架,比較可靠好用的如xUtils,Glide,volley,Universal-Image-Loader,Picasso,Fresco等等。

下面我們以常用的xUtils為例首先對(duì)BitmapUtils的實(shí)例化,對(duì)于磁盤緩存路徑,磁盤緩存空間大小,內(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);

然后對(duì)圖片的緩存和顯示

 /**
 * 根據(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í),會(huì)根據(jù)圖片地址進(jìn)行查找是否有對(duì)應(yīng)的bitmap緩存圖片,如果有就直接引用緩存,如果沒有就加載并緩存,所以我們對(duì)圖片的緩存只需要實(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ù)字有變化,就會(huì)自動(dòng)去更新

3.利用socket監(jiān)聽,當(dāng)好友頭像更新時(shí)候首先會(huì)告訴服務(wù)器,服務(wù)器將變化通知推送到所有好友,好友監(jiān)聽收到通知后自動(dòng)更新
第一種方法和第二種方法本質(zhì)是一致的,通過請(qǐng)求服務(wù)器的數(shù)據(jù)與本地緩存進(jìn)行對(duì)比,是由客戶端處理的,第三種方法的話你換一次頭像就要服務(wù)器去提醒你的所有好友一遍,服務(wù)器壓力會(huì)不會(huì)比較大

仔細(xì)去研究一下微信,就會(huì)發(fā)現(xiàn),當(dāng)好友頭像修改后,如果你停留在某個(gè)頁面,進(jìn)入的這個(gè)頁面是之前進(jìn)入過的,還沒有銷毀,頭像是不會(huì)改變的,你需要打開一個(gè)新的頁面或者重新進(jìn)入微信,才會(huì)更新頭像,由此看出,微信并不是用的第三種方式,而是采用了前兩種方式的實(shí)現(xiàn)原理,只有在創(chuàng)建一個(gè)Activity或fragment時(shí),調(diào)用接口,讀取服務(wù)器數(shù)據(jù)時(shí)才會(huì)更新頭像

總結(jié)

通過以上的分析,我們基本捋清了思路,要實(shí)現(xiàn)類似微信的緩存和更新還有頭像,先是在磁盤開辟一個(gè)空間,用于讀寫頭像的Bitmap,然后創(chuàng)建頁面時(shí),讀取服務(wù)器數(shù)據(jù)和本地緩存進(jìn)行比較,如果有變化就進(jìn)行更新

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android Flutter利用貝塞爾曲線畫一個(gè)小海豚

    Android Flutter利用貝塞爾曲線畫一個(gè)小海豚

    貝塞爾曲線的應(yīng)用填補(bǔ)了計(jì)算機(jī)繪制與手繪之前的差距,更能表達(dá)人想畫出的曲線。本文就將利用貝塞爾曲線繪制一個(gè)可愛的小海豚,需要的可以參考一下
    2022-04-04
  • Android顯式Intent與隱式Intent的使用詳解

    Android顯式Intent與隱式Intent的使用詳解

    Intent的中文意思是“意圖,意向”, Intent對(duì)Android的核心和靈魂,是各組件之間的橋梁。四大組件分別為Activity 、Service、BroadcastReceiver、ContentProvider。而這四種組件是獨(dú)立的,它們之間可以互相調(diào)用,協(xié)調(diào)工作,最終組成一個(gè)真正的Android應(yīng)用
    2022-09-09
  • 詳解Android系統(tǒng)啟動(dòng)過程

    詳解Android系統(tǒng)啟動(dòng)過程

    這篇文章主要介紹了Android系統(tǒng)啟動(dòng)過程的相關(guān)資料,幫助大家更好得理解和學(xué)習(xí)使用Android,感興趣的朋友可以了解下
    2021-03-03
  • Android 獲取內(nèi)外SD卡路徑幾種方法總結(jié)

    Android 獲取內(nèi)外SD卡路徑幾種方法總結(jié)

    這篇文章主要介紹了Android 獲得內(nèi)外SD卡路徑幾種方法總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • 淺析Kotlin使用infix函數(shù)構(gòu)建可讀語法流程講解

    淺析Kotlin使用infix函數(shù)構(gòu)建可讀語法流程講解

    這篇文章主要介紹了淺析Kotlin使用infix函數(shù)構(gòu)建可讀語法,我們?cè)贙otlin中就多次使用A to B這樣的語法結(jié)構(gòu)構(gòu)建鍵值對(duì),包括Kotlin自帶的mapOf()函數(shù),這種語法結(jié)構(gòu)的優(yōu)點(diǎn)是可讀性強(qiáng)
    2023-01-01
  • Android6.0獲取GPS定位和獲取位置權(quán)限和位置信息的方法

    Android6.0獲取GPS定位和獲取位置權(quán)限和位置信息的方法

    今天小編就為大家分享一篇Android6.0獲取GPS定位和獲取位置權(quán)限和位置信息的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • Android實(shí)現(xiàn)歷史搜索記錄

    Android實(shí)現(xiàn)歷史搜索記錄

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)歷史搜索記錄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Android開發(fā)之簡(jiǎn)單文件管理器實(shí)現(xiàn)方法

    Android開發(fā)之簡(jiǎn)單文件管理器實(shí)現(xiàn)方法

    這篇文章主要介紹了Android開發(fā)之簡(jiǎn)單文件管理器實(shí)現(xiàn)方法,簡(jiǎn)單實(shí)現(xiàn)了Android的文件目錄查看,文件重命名,打開,刪除等功能,需要的朋友可以參考下
    2016-01-01
  • Android利用FlexboxLayout輕松實(shí)現(xiàn)流動(dòng)布局

    Android利用FlexboxLayout輕松實(shí)現(xiàn)流動(dòng)布局

    flexbox是屬于CSS的一種布局方案,可以簡(jiǎn)單、完整、響應(yīng)式的實(shí)現(xiàn)各種頁面布局。谷歌將其引入以提高復(fù)雜布局的能力。下面這篇文章主要給大家介紹了在Android中利用FlexboxLayout輕松實(shí)現(xiàn)流動(dòng)布局的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-04-04
  • Flutter實(shí)現(xiàn)webview與原生組件組合滑動(dòng)的示例代碼

    Flutter實(shí)現(xiàn)webview與原生組件組合滑動(dòng)的示例代碼

    這篇文章主要介紹了Flutter實(shí)現(xiàn)webview與原生組件組合滑動(dòng)的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03

最新評(píng)論

灵台县| 大埔区| 兴仁县| 泽库县| 阿克陶县| 会理县| 贵德县| 望江县| 扶绥县| 苏州市| 阿巴嘎旗| 洱源县| 柘荣县| 双牌县| 潍坊市| 扎兰屯市| 安图县| 江山市| 天津市| 宁国市| 凤翔县| 平乡县| 常熟市| 庆云县| 两当县| 房产| 从化市| 哈尔滨市| 靖安县| 伊宁市| 阿克苏市| 唐山市| 寿宁县| 新乡县| 眉山市| 葵青区| 延津县| 中阳县| 西平县| 宁津县| 大兴区|