Как отписаться от вызова RXjava в широковещательном приемнике

Я использую RXJava2 для отправки электронной почты в широковещательном приемнике, и я хотел бы знать, когда я должен отказаться от подписки на событие. Код в основном:

        getSmsMmsObservable()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnError(throwable -> Timber.e(throwable, "Error sending mail."))
            .map(smsMmsAddress1 -> {
                smsMmsAddress = smsMmsAddress1;
                return doInBackgroundSendEmail();
            })
            .map(stringSingle -> {
                mMsgResponse = stringSingle;
                this.done = true;
                return deleteFile();
            })
            .subscribe(success -> {
                if (success) {
                    Toast.makeText(context, "Message Status: " + mMsgResponse, Toast.LENGTH_LONG).show();
                }

            });

Когда мне отписаться (в приемнике нет onPause или onDestroy) и как я узнаю, что onReceive завершен? Получатель регистрируется через манифест. Я подумал о том, чтобы сделать составную наблюдаемую, а затем избавиться от нее в разделе subscribe().

    compositeDisposable.add(
    getSmsMmsObservable()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .doOnError(throwable -> Timber.e(throwable, "Error sending mail."))
            .map(smsMmsAddress1 -> {
                smsMmsAddress = smsMmsAddress1;
                return doInBackgroundSendEmail();
            })
            .map(stringSingle -> {
                mMsgResponse = stringSingle;
                this.done = true;
                return deleteFile();
            })
            .subscribe(success -> {
                if (success) {
                    Toast.makeText(context, "Message Status: " + mMsgResponse, Toast.LENGTH_LONG).show();
                }
                compositeDisposable.dispose();

            })
    );

person Kristy Welsh    schedule 15.08.2017    source источник
comment
попробуйте сделать это действие в сервисе вместо ресивера   -  person Illya Bublyk    schedule 16.08.2017
comment
Я не могу, мне нужно вызвать это действие при получении текста.   -  person Kristy Welsh    schedule 16.08.2017
comment
вы должны запустить службу и отправить ему текст. Другое решение - Android убьет приемник через 10 секунд после вызова onReceive()   -  person Illya Bublyk    schedule 16.08.2017


Ответы (1)


Как указано здесь, вы не должны выполнять длительные задачи на широковещательном приемнике.
У широковещательных приемников нет жизненного цикла, когда ваш onReceive возвращает, он считается выполненным системой, и весь ваш процесс впоследствии может быть уничтожен, он немедленно вернется ваш случай, когда вы выполняете асинхронную обработку. (подробнее читайте здесь https://developer.android.com/guide/components/broadcasts.html в разделе «Влияние на состояние процесса»).

Вы должны создать специальную службу для этой задачи и выполнять отправку электронной почты туда, с услугой, у вас есть четкий жизненный цикл, и вы должны отказаться от подписки в onDestory(). также обратите внимание на ограниченную фоновую обработку и доступ в Интернет, начиная с Marshmallow и Doze.

В любом случае вы не должны удалять в onNext/onCompleted, Observable вызовет логику удаления, когда он завершится (onCompleted/onError).

person yosriz    schedule 16.08.2017