2017-04-21 18 views
1

RxJavaを使用するために、サーバにメッセージを送信するAsyncTaskを移行しようとしています。おおよそ、タスクは次のない:RxJavaで長時間実行するタスクを処理する

1)送信されるメッセージ(データベースへの持続)
2を作成し)、ユーザ(状態「送信」)
3にメッセージを表示)メッセージを送信)サーバー(以下のコードスニペット)
4に送信されたとしてメッセージをマークしたか失敗した(データベースへの持続)
5)私は部分的にこのようになり、必要な受信チェーンを作成したUI

を更新します:

public Observable<Message> sendMessage(Message message) { 
    return mApiClient.sendMessage(message) 
     .doOnNext(sentMessage -> mDatabase.synchroniseMessage(sentMessage)) 
     .doOnError(e -> { 
      message.setState(FAILED); 
      mDatabase.synchroniseMessage(message)); 
     }) 
     .onErrorReturn(e -> Observable.just(message)); 

上記を購読すると、Disposableとなります。通常、私はそれをCompositeDisposableオブジェクトに追加し、そのオブジェクトに対応するclearを追加して、別のview(つまりfragment)に移動しました。ただし、この場合は、ローカルデータベースがタスク結果に応じて更新されるように、このタスクを実行しておく必要があります。

この状況を処理する最も適切な方法は何でしょうか?私は単にDisposableを私のCompositeDisposableオブジェクトに追加することはできません。そのため、登録解除されませんが、問題を引き起こす可能性があります。

P.S.ユーザーへの更新を表示するには、SQLiteテーブルのデータを観察します。これらのイベントは、synchroniseMessageメソッドによってトリガーされます。これは私が単純に退会する異なるサブスクリプションなので、問題の一部ではありません。

答えて

2

1人は、もはや彼が興味を持たなくなるとすぐにDisposableを処分します。

ユーザーが別の画面にナビゲートするかどうかにかかわらずストリームに興味がある場合は、そのストリームからの参加を拒否できません。つまり、CompositeDisposableに追加することはできません。

Subscriptionからの暗黙的な参照のために、Activityがガベージコレクションできない状況が発生するため、メモリリーク状況が発生します。

このようなユースケースがある場合は、アクティビティのライフサイクルに依存しないコンポーネント(たとえば、Service)に対してそのリクエストを実行する必要があると思います。

+0

私は本当に 'サービス'の使用や 'AsyncTask'の使用を避けたいと思います。それは私のアーキテクチャに影響を与えるだけでなく、ユニットテストのための私のオプションを減らすことになります。私は「Disposable」への参照を保持しないと、それが最終的に(15秒の 'OkHttp'タイムアウト期間)終了し、サブスクリプションを処分することが危険なことを理解しようとしています。どこかにアクセス可能で、いつも毎回ディスポーザブルをポーリングするポーリングタスクを持っています。 – vkislicins

+0

私が見る唯一の問題は、あなたの 'Activity'がわずか15秒間所有しているメモリを再利用するためにGCをブロックすることです。その後、次のGCイベントは通常、アクティビティをクリーンアップします。だから、基本的に、あなたは悪い少年のようにわずか15秒間行動しています。 – azizbekian

+0

しかし、ユーザーがローテーションデバイスを複数回連続しておき、そのたびに再度購読すると、 'OutOfMemoryException'が発生します。 – azizbekian

関連する問題