5

Android アプリで RxJava を使用していますが、OutOfMemoryError が数回発生しました。デバイス マネージャーで確認したところ、200 を超えるスレッドがあり、そのほとんどが待機状態であり、通常は RxCachedThreadSchedulers であることに気付きました。スレッドが多すぎるため、OOMError が発生します。また、サービスを呼び出してトークンを取得してキャッシュするボタンを押すと、スレッド数が 5 増加することにも気付きました。

それで、私はググって、Schedulers.ioが無制限のスレッドを作成できることを発見しました。すべての Schedulers.io を Schedulers.computation に置き換えると、問題はなくなりますが、Schedulers.io を本来の使用方法で使用しているため、意味がありません。

では、Schedulers.io を使用して、スレッドが多すぎないようにするにはどうすればよいでしょうか?

アップデート

私はこのように退会を行います:

    final Scheduler.Worker worker = Schedulers.io().createWorker();
    worker.schedule(new Action0() {
        @Override
        public void call() {
            long last = lastServerCommunication.getMillis();
            LongPreference pref = new LongPreference(mSharedPreferences, PREF_KEY_LAST_SERVER_COMMUNICATION);
            pref.set(last);
            worker.unsubscribe();
        }
    });

アップデート #2

私が定期的に Schedulers.io を使用する方法は次のとおりです。

public Observable<Scenario> load() {
    return Observable
            .create(new Observable.OnSubscribe<Scenario>() {
                @Override
                public void call(Subscriber<? super Scenario> subscriber) {
                    try {
                        Scenario scenario = mGson.fromJson(mSharedPreferences.getString("SCENARIO", null), Scenario.class);
                        subscriber.onNext(scenario);
                        subscriber.onCompleted();
                    } catch (Exception e) {
                        subscriber.onError(new Throwable());
                    }
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
}

と:

    mSomeSubscription = mSomeManager.readFromDatabase()
            .subscribeOn(Schedulers.io())
            .subscribe(new Observer<List<SomeEntry>>() {
                @Override
                public void onCompleted() { }

                @Override
                public void onError(Throwable e) {
                    // some logging
                }

                @Override
                public void onNext(List<SomeEntry> Entries) {
                    // Some action
                }
            });
4

3 に答える 3

5

わかりました、理由がわかりました。説明、更新 #2を参照してください。

return Observable.create(new Observable.OnSubscribe<Something>() {
            @Override
            public void call(Subscriber<? super Something> subscriber) {
                try {
                  // Some action
                    subscriber.onNext(scenario);
                    subscriber.onCompleted();
                } catch (Exception e) {
                    subscriber.onError(new Throwable());
                }
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());

このようなコールド Observable シーケンスを作成するときは、サブスクライバーで onCompleted を呼び出すことを確認する必要があります。上記を参照してくださいsubscriber.onCompleted();。まあ、コードのいくつかの場所にそれがなかったので、io スレッドが生成されました。

助けてくれてありがとうakarnokd

于 2015-07-09T15:36:30.923 に答える
1

素晴らしいです。onComplete メソッドを呼び出さないと、(によって作成されたSchedulers.io()) スレッドは待機し続け、コールド オブザーバブルのために存在します。

于 2016-07-15T10:34:57.957 に答える