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

使用RxJava中遇到的一些”坑“

 更新時間:2017年05月26日 10:18:20   作者:lshw4320814  
這篇文章主要給大家介紹了在使用RxJava中可能遇到的一些”坑“,文中總結(jié)的這些坑都是我在實踐中遇到的,現(xiàn)在分享出來給大家,希望大家能夠避免這個問題,需要的朋友們下面來一起看看吧。

前言

大家越用RxJava,越覺得它好用,所以不知不覺地發(fā)現(xiàn)代碼里到處都是RxJava的身影。然而,RxJava也不是銀彈,其中仍然有很多問題需要解決。這里,我簡單地總結(jié)一下自己遇到的一些“坑”,內(nèi)容上可能會比較松散。

一、考慮主線程的切換

RxJava中一個常用的使用方法是——在其他線程中做處理,然后切換到UI線程中去更新頁面。其中,線程切換就是使用了observeOn()。后臺下載文件,前臺顯示下載進度就可以使用這種方式完成。然而,實踐發(fā)現(xiàn)這其中有坑。如果文件比較大,而下載包的粒度又比較小,這將導(dǎo)致很多通知積壓下來,最終導(dǎo)致錯誤。

這種錯誤其實也是可以理解的,畢竟MainLooper是根據(jù)Message來工作的,Message過多必然會導(dǎo)致一些問題。當(dāng)然,這還是比較想當(dāng)然的想法,最終還是需要到源碼中一探究竟。ObserveOn的原理在前面關(guān)于RxJava的文章已經(jīng)有過分析,這里還是簡單列一下代碼。其中的重點還是OperatorObserveOn的內(nèi)部類——ObserveOnSubscriber。其重要代碼片段如下:

 /** Observe through individual queue per observer. */
 static final class ObserveOnSubscriber<T> extends Subscriber<T> implements Action0 {
  final Subscriber<? super T> child;
  final Scheduler.Worker recursiveScheduler;
  final NotificationLite<T> on;
  final boolean delayError;
  final Queue<Object> queue;
  /** The emission threshold that should trigger a replenishing request. */
  final int limit;

  // the status of the current stream
  volatile boolean finished;

  final AtomicLong requested = new AtomicLong();

  final AtomicLong counter = new AtomicLong();

  /**
   * The single exception if not null, should be written before setting finished (release) and read after
   * reading finished (acquire).
   */
  Throwable error;

  /** Remembers how many elements have been emitted before the requests run out. */
  long emitted;

  // do NOT pass the Subscriber through to couple the subscription chain ... unsubscribing on the parent should
  // not prevent anything downstream from consuming, which will happen if the Subscription is chained
  public ObserveOnSubscriber(Scheduler scheduler, Subscriber<? super T> child, boolean delayError, int bufferSize) {
   this.child = child;
   this.recursiveScheduler = scheduler.createWorker();
   this.delayError = delayError;
   this.on = NotificationLite.instance();
   int calculatedSize = (bufferSize > 0) ? bufferSize : RxRingBuffer.SIZE;
   // this formula calculates the 75% of the bufferSize, rounded up to the next integer
   this.limit = calculatedSize - (calculatedSize >> 2);
   if (UnsafeAccess.isUnsafeAvailable()) {
    queue = new SpscArrayQueue<Object>(calculatedSize);
   } else {
    queue = new SpscAtomicArrayQueue<Object>(calculatedSize);
   }
   // signal that this is an async operator capable of receiving this many
   request(calculatedSize);
  }

  void init() {
   // don't want this code in the constructor because `this` can escape through the
   // setProducer call
   Subscriber<? super T> localChild = child;

   localChild.setProducer(new Producer() {

    @Override
    public void request(long n) {
     if (n > 0L) {
      BackpressureUtils.getAndAddRequest(requested, n);
      schedule();
     }
    }

   });
   localChild.add(recursiveScheduler);
   localChild.add(this);
  }

  @Override
  public void onNext(final T t) {
   if (isUnsubscribed() || finished) {
    return;
   }
   if (!queue.offer(on.next(t))) {
    onError(new MissingBackpressureException());
    return;
   }
   schedule();
  }

  @Override
  public void onCompleted() {
   if (isUnsubscribed() || finished) {
    return;
   }
   finished = true;
   schedule();
  }

  @Override
  public void onError(final Throwable e) {
   if (isUnsubscribed() || finished) {
    RxJavaHooks.onError(e);
    return;
   }
   error = e;
   finished = true;
   schedule();
  }

  protected void schedule() {
   if (counter.getAndIncrement() == 0) {
    recursiveScheduler.schedule(this);
   }
  }
 }

關(guān)鍵點就在于這個queue成員,這個隊列存放了需要進行發(fā)送給下行線程的消息。對于主線程來說,符合其實是比較重的,從消息的生產(chǎn)者和消費者的模式講,過多過快的消息會導(dǎo)致消息阻塞。甚至,都到不了阻塞的情況,因為queue的大小會有上限,在onNext()方法中的queue.offer()可能會產(chǎn)生異常,這取決于queue的實現(xiàn)方式。但無論如何都不可能無限大,所以無法保證絕對不出異常。

解決這個問題的方法其實也很簡單,可以在生產(chǎn)者降低消息的產(chǎn)生頻率。也可以在消息處理的時候先不進行線程切換,而是通過判斷,在必要的時候進行線程切換,比如使用runOnUIThread() 。

二、RxJava避免內(nèi)存泄漏

RxJava的響應(yīng)式機制本質(zhì)上還是回調(diào)實現(xiàn)的,因此內(nèi)存泄漏也是會出現(xiàn)的。倘若不對Subscription進行管理,內(nèi)存泄漏會非常嚴重。對于Subscription,其實有幾個比較廣泛使用的方法,比如RxLifecycle,以及簡單的CompositeSubscription。至于它們的使用方法,其實都非常簡單,這里就不贅述了。

說到內(nèi)存泄漏,就談點題外話,動畫也可能導(dǎo)致內(nèi)存泄漏。其原因仍然是一些回調(diào)函數(shù),這些回調(diào)函數(shù)實現(xiàn)的View變化的功能,但是在被撤銷以后,回調(diào)函數(shù)沒有取消掉,同時View可能持有Context信息,從而導(dǎo)致內(nèi)存泄漏。最近才發(fā)現(xiàn),LoadToastView這個開源庫一直存在內(nèi)存泄漏,其原因正如上文所說。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • Android隱私彈框功能的實現(xiàn)

    Android隱私彈框功能的實現(xiàn)

    最近做app類的項目,現(xiàn)在發(fā)布app都需要在發(fā)布前生成一個用戶隱私彈框讓用戶點擊,這個功能看似簡單,到底怎么實現(xiàn)的呢?下面小編給大家?guī)砹薃ndroid隱私彈框功能的實現(xiàn)代碼,一起看看吧
    2021-10-10
  • android實現(xiàn)多線程斷點續(xù)傳功能

    android實現(xiàn)多線程斷點續(xù)傳功能

    這篇文章主要為大家詳細介紹了android實現(xiàn)多線程斷點續(xù)傳功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Android ExpandableListView單選以及多選實現(xiàn)代碼

    Android ExpandableListView單選以及多選實現(xiàn)代碼

    這篇文章主要為大家詳細介紹了Android ExpandableListView單選以及多選的實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Android 使用registerReceiver注冊BroadcastReceiver案例詳解

    Android 使用registerReceiver注冊BroadcastReceiver案例詳解

    這篇文章主要介紹了Android 使用registerReceiver注冊BroadcastReceiver案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 使用SharedPreferences在Android存儲對象詳細代碼

    使用SharedPreferences在Android存儲對象詳細代碼

    這篇文章主要介紹了使用SharedPreferences在Android存儲對象并附上詳細代碼,下面文章內(nèi)容較少,大多以代碼的形式體現(xiàn),需要的小伙伴可以參考一下,希望對你有所幫助
    2021-11-11
  • Android 3.0引入的異步加載機制Loader

    Android 3.0引入的異步加載機制Loader

    Loader裝載器從android3.0開始引進。它使得在activity或fragment中異步加載數(shù)據(jù)變得簡單。下面我們就來詳細講解下
    2017-12-12
  • 教你安裝配置Android Studio

    教你安裝配置Android Studio

    對于Android Studio相信大家都不陌生了,作為谷歌推出的安卓開發(fā)工具,做過java的同學(xué)應(yīng)該都了解,下面我們就簡單介紹下這款工具的安裝預(yù)配置
    2015-12-12
  • Android自定義TextView仿微信朋友圈文字展開全文功能

    Android自定義TextView仿微信朋友圈文字展開全文功能

    這篇文章主要為大家詳細介紹了Android自定義TextView仿微信朋友圈文字展開全文功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Android ToolBar 修改邊距的實現(xiàn)方法

    Android ToolBar 修改邊距的實現(xiàn)方法

    這篇文章主要介紹了Android ToolBar 修改邊距的實現(xiàn)方法的相關(guān)資料,通過此文希望能幫助到大家,需要的朋友可以參考下
    2017-08-08
  • Android利用AudioRecord類實現(xiàn)音頻錄制程序

    Android利用AudioRecord類實現(xiàn)音頻錄制程序

    這篇文章主要為大家詳細介紹了Android利用AudioRecord類實現(xiàn)音頻錄制程序,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04

最新評論

钟祥市| 清丰县| 伊春市| 陆河县| 宜宾市| 丹棱县| 东源县| 庐江县| 杭锦后旗| 山东省| 连云港市| 萝北县| 武安市| 水城县| 内黄县| 大名县| 黑水县| 乌兰浩特市| 麟游县| 瑞金市| 甘德县| 沂源县| 德州市| 廊坊市| 精河县| 建湖县| 伊吾县| 东阿县| 吴忠市| 汉沽区| 安阳市| 抚松县| 博爱县| 日喀则市| 铜陵市| 墨脱县| 正安县| 滨海县| 蒙阴县| 合川市| 拉孜县|