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

Android異步回調(diào)中的UI同步性問題分析

 更新時間:2016年06月01日 16:27:11   作者:Windstep  
這篇文章主要為大家詳細分析了Android異步回調(diào)中的UI同步性問題,感興趣的小伙伴們可以參考一下

Android程序編碼過程中,回調(diào)無處不在。從最常見的Activity生命周期回調(diào)開始,到BroadcastReceiver、Service以及Sqlite等。Activity、BroadcastReceiver和Service這些基本組件的回調(diào)路徑和過程也就是通常意義上所謂的“生命周期”。同時,在處理具體的業(yè)務邏輯時,常常設計到不同線程之間的通信,如下載圖片完成后通知 UI線程更新UI,凡此類場景,無論使用哪一種具體的線程間通信方式(Handler/Message、Handler/post、基于接口的回調(diào)、基于多對多的觀察者模式如EventBus等),其本質(zhì)上都是基于“回調(diào)”。在實際編碼過程中,凡涉及到不同線程之間的通信,本質(zhì)上更是屬于“異步回調(diào)”。當需要在“異步回調(diào)”中修改UI時,此時需要特別注意UI同步性問題。

為了便于問題的闡述,在此先對“Android異步回調(diào)UI同步性問題”進行如下界定:當異步回調(diào)執(zhí)行時(稱之為“異步回調(diào)執(zhí)行點”),當前UI界面上的元素與最初生成此異步回調(diào)的調(diào)用器開始執(zhí)行時(稱之為“異步回調(diào)生成點”)的UI元素已經(jīng)存在不一致,不一致不僅包括UI元素可能的界面變化、可能的內(nèi)容變化,也包括“異步回調(diào)執(zhí)行點”和“異步回調(diào)生成點”時的UI元素中的某一特性的表征量(如某一具有表征當前UI元素的字段值)相關,即使UI元素界面和內(nèi)容都尚未發(fā)生變化。

編碼過程中,“Android異步回調(diào)UI同步性問題”經(jīng)常存在,有時候稍不注意會產(chǎn)生一些看起來難以理解的bug,并由于異步特性的存在,此類bug還具有一定的隨機性。有時候由于一些需求的復雜性,此類bug隱蔽性很強,也容易被忽略。至少到目前為止,在實際開發(fā)中,本人遇到此類問題已有數(shù)個。

純文字的描述可能不太好理解,下面以一個很常用的Android-Universal-Image-Loader為例,簡單舉例一個潛在存在的“Android異步回調(diào)UI同步性問題”。

ListView Item View中有ImageView,通過Android-Universal-Image-Loader去加載顯示,圖片加載完成后需要做一些邏輯處理(如隱藏圖片加載進度條等..),通常代碼如下:

ImageLoader.getInstance().loadImage(imageUrl, new ImageLoadingListener() {
        
 @Override
 public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
  if (loadedImage != null) {
   imageView.setImageBitmap(loadedImage);
   // 其他業(yè)務邏輯處理..
  }
 }

 @Override
 public void onLoadingStarted(String imageUri, View view) {
  
 }

 @Override
 public void onLoadingCancelled(String arg0, View arg1) {
  
 }

 @Override
 public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {
  
 }
});

初看上去,代碼邏輯好像也沒什么問題,網(wǎng)上大部分人也是這么寫的。當較慢滑動ListView時,或在平時正常使用時,也沒有什么問題。但是此處的代碼邏輯真的嚴密嗎?

ListView的getView復用特性,大家也都熟知。對于之前遇到的“圖片錯位/先顯示之前的圖片后再被正確的圖片覆蓋掉”,此類現(xiàn)象也都知道如何解決(在getView邏輯開始處理處將ImageView設置成最先的默認圖片,其他UI元素類似處理),基本上也不會再有“圖片錯位/先顯示之前的圖片后再被正確的圖片覆蓋掉”這類現(xiàn)象了。實際上,當網(wǎng)速條件一般,且loadImage大致與上述代碼所示,在ListView中快速滑動列表,幾屏后,不出意外,會發(fā)現(xiàn)“圖片錯位/先顯示之前的圖片后再被正確的圖片覆蓋掉”此問題依然存在。

此時問題出現(xiàn)的原因不在于getView本身,因為getView邏輯開始時已經(jīng)將ImageView重置為默認圖片,而在于“Android異步回調(diào)UI同步性問題”。由于ViewHolder的不斷復用,網(wǎng)速一般時快速滑動幾屏后,onLoadingComplete的異步回調(diào)執(zhí)行時與當前UI元素已經(jīng)存在不一致,簡單點理解,ImageView被復用了ImageView position 0,ImageView position 11, ImageView position 21,此時滑動停止,onLoadingComplete的異步回調(diào)執(zhí)行時ImageView已經(jīng)是最后一次的ImageView position 21,而onLoadingComplete的異步回調(diào)可能被執(zhí)行數(shù)次(ImageView position 0,ImageView position 11, ImageView position 21,且順序還取決于異步中的具體處理和網(wǎng)絡環(huán)境等),于是問題發(fā)生了。

解決方案:
抓住”UI元素中的某一特性的表征量“,在異步回調(diào)中通過比較“異步回調(diào)生成點”和“異步回調(diào)執(zhí)行點”此特征變量的值直接作出邏輯上的處理。

public class HardRefSimpleImageLoadingListener implements ImageLoadingListener {

 public int identifier;

 public HardRefSimpleImageLoadingListener() {
 }

 public HardRefSimpleImageLoadingListener(int identifier) {
  this.identifier = identifier;
 }

 @Override
 public void onLoadingCancelled(String arg0, View arg1) {

 }

 @Override
 public void onLoadingComplete(String arg0, View arg1, Bitmap arg2) {

 }

 @Override
 public void onLoadingFailed(String arg0, View arg1, FailReason arg2) {

 }

 @Override
 public void onLoadingStarted(String arg0, View view) {
 
 }
}

ImageLoader.getInstance().loadImage(imageUrl, new HardRefSimpleImageLoadingListener(did) {
 @Override
 public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
  if (loadedImage != null) {
   if (identifier != did) {
    return;
   }
   imageView.setImageBitmap(loadedImage);
   // 其他業(yè)務邏輯處理..
  }
 }
});


總之,凡此類“Android異步回調(diào)UI同步性問題”,最好都通過比較“異步回調(diào)生成點”“異步回調(diào)執(zhí)行點”特征變量的值去針對性的做邏輯處理,以免出現(xiàn)不必要的Bug,是非常必要且有效的手段。

 原文地址:http://www.cnblogs.com/lwbqqyumidi/p/4110377.html

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Android onLoadFinished與onLoaderReset回調(diào)詳解及實例

    Android onLoadFinished與onLoaderReset回調(diào)詳解及實例

    這篇文章主要介紹了Android onLoadFinished與onLoaderReset回調(diào)詳解及實例的相關資料,需要的朋友可以參考下
    2017-03-03
  • Android編程實用技術小結(jié)

    Android編程實用技術小結(jié)

    這篇文章主要介紹了Android編程實用技術,實例匯總了開機啟動receiver、service使用、AlarmManager發(fā)送廣播及停止AlarmManager等相關技巧,需要的朋友可以參考下
    2016-01-01
  • Android PopupWindow實現(xiàn)遮罩層效果

    Android PopupWindow實現(xiàn)遮罩層效果

    這篇文章主要為大家詳細介紹了Android PopupWindow實現(xiàn)遮罩層效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • Android RollPagerView實現(xiàn)輪播圖

    Android RollPagerView實現(xiàn)輪播圖

    這篇文章主要介紹了Android RollPagerView實現(xiàn)輪播圖的相關資料,這里提供實例來實現(xiàn)輪播圖的簡單實例,希望能幫助到大家,需要的朋友可以參考下
    2017-08-08
  • Android快速實現(xiàn)觸摸移動的懸浮窗

    Android快速實現(xiàn)觸摸移動的懸浮窗

    這篇文章主要為大家詳細介紹了Android快速實現(xiàn)觸摸移動的懸浮窗,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • android通過藍牙接收文件打開時無法自動選擇合適的應用程序

    android通過藍牙接收文件打開時無法自動選擇合適的應用程序

    android 通過藍牙接收文件,從歷史傳輸記錄打開,無法自動選擇合適的應用程序,比如video player打開.3gp、.mp4文件等等
    2013-06-06
  • Flutter質(zhì)感設計之列表項

    Flutter質(zhì)感設計之列表項

    這篇文章主要為大家詳細介紹了Flutter質(zhì)感設計之列表項,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Android中巧妙的實現(xiàn)緩存詳解

    Android中巧妙的實現(xiàn)緩存詳解

    采用緩存,可以進一步大大緩解數(shù)據(jù)交互的壓力,有的時候為了快速查詢會被多次調(diào)用的數(shù)據(jù),或者構建比較廢時的實例,我們一般使用緩存的方法。無論大型或小型應用,靈活的緩存可以說不僅大大減輕了服務器的壓力,而且因為更快速的用戶體驗而方便了用戶。下面來一起看看吧。
    2016-11-11
  • Android中XUtils3框架使用方法詳解(一)

    Android中XUtils3框架使用方法詳解(一)

    這篇文章主要介紹了Android中XUtils3框架使用方法詳解(一)的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-08-08
  • Android監(jiān)聽滑動控件實現(xiàn)狀態(tài)欄顏色切換

    Android監(jiān)聽滑動控件實現(xiàn)狀態(tài)欄顏色切換

    這篇文章給大家分享一個平時在滑動頁面經(jīng)常遇到的效果:滑動過程動態(tài)修改狀態(tài)欄顏色,文中有詳細的示例代碼,對我們的學習或工作有一定的幫助,感興趣的小伙伴自己動手試試吧
    2023-08-08

最新評論

玛纳斯县| 宝山区| 年辖:市辖区| 张家港市| 花莲县| 全椒县| 高唐县| 绥棱县| 梁河县| 师宗县| 阳西县| 盐城市| 邳州市| 黑山县| 图们市| 大安市| 安岳县| 叶城县| 巫山县| 绍兴县| 游戏| 三台县| 德保县| 化州市| 西吉县| 南岸区| 五台县| 桂阳县| 金秀| 陆河县| 白城市| 革吉县| 喀什市| 长宁区| 宁城县| 上犹县| 高州市| 陆良县| 湖州市| 葫芦岛市| 湖北省|