android - 销毁 Activity 时在订阅外注销 BroadcastReceiver

标签 android bluetooth broadcastreceiver rx-java rx-android

我有这个小实用方法,可以让我获得一个 Observable 来监控蓝牙状态。

public static Observable<Integer> getBluetoothStateObservable(Context context) {
    final Context appContext = context.getApplicationContext();
    return Observable.create(observer -> {
            final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    int btState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.STATE_OFF);
                    switch (btState) {
                        case BluetoothAdapter.ERROR:
                            observer.onError(new IllegalArgumentException("Error occurred while changing bluetooth state"));
                            break;
                        case BluetoothAdapter.STATE_OFF:
                        case BluetoothAdapter.STATE_ON:
                            observer.onCompleted();
                            break;
                        default:
                            observer.onNext(btState);
                            break;
                    }
                }
            };
            observer.add(Subscriptions.create(() -> appContext.unregisterReceiver(broadcastReceiver)));
            appContext.registerReceiver(broadcastReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
    })
}

当我在 Activity 中使用此方法时,我知道用户何时启用了蓝牙。这工作正常,但当 Activity 突然被杀死时它会泄漏。

我可以在onDestroy中取消订阅,但是如何取消注册BroadcastReceiver

有什么想法吗?

最佳答案

鉴于 getBluetoothStateObservable 的设置方式,BroadcastReceiver 将在订阅者取消订阅时取消注册。唯一的技巧是确保它确实在 Android Activity 生命周期开始运行时取消订阅。

在这种情况下,您可以保留订阅实例,也可以使用复合订阅。

在 onCreate 或 onStart 中(例如):

mSubscription = getBluetoothStateObservable(this).subscribe();
or 
mCompositeSubscription.add(getBluetoothStateObservable(this).subscribe());

在 onDestroy 或 onStop 中:

mSubscription.unsubscribe();
or
mCompositeSubscription.clear();

一如既往,Dan Lew 对 Android 生命周期应如何与 RxJava 协同工作做出了很好的解释 (http://blog.danlew.net/2014/10/08/grokking-rxjava-part-4/)

关于android - 销毁 Activity 时在订阅外注销 BroadcastReceiver,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38341031/

相关文章:

Android Intent 有时是 "handled"而不是 ACTION_SEND

android - 关闭来自 BroadCastReceiver 的通知

java - 在 BroadcastReceiver 上使用 newInstance 时出现 InstantiationException

Android 等宽空格 ( ) 宽度与字符宽度不同

java - 如何解析包含数组的空值 JSON

java - Android静态变量丢失

iphone - 当外部配件通过 BT 配对或插入底座连接器时如何启动 iPhone 应用程序

java - 获取 java.io.IOException : read failed, 套接字可能已关闭或在 BluetoothSocket.connect() 上超时

macos - 切换蓝牙的 AppleScript

Android 从 Fragment 设置闹钟