【问题标题】:Unregistering Broadcast Receiver error注销广播接收器错误
【发布时间】:2016-03-10 08:38:06
【问题描述】:

我想在我的 android 应用程序中获取可用的蓝牙设备,以便我可以通过我的应用程序配对或不公平的设备。我正在注册一个广播接收器来通知我的新设备列表。我在活动中执行此操作,但是当我使用 finish() 销毁我的活动时,即使我正在取消注册接收器,它仍然给我以下错误。

例外:

03-10 10:24:48.790 25219-25219/com.vidame E/ActivityThread: Activity com.vidame.Activities.BloodPressureActivity has leaked IntentReceiver com.vidame.HelperClasses.Bluetooth$mPairReceiver@37341ff5 that was originally registered here. Are you missing a call to unregisterReceiver()?
android.app.IntentReceiverLeaked: Activity com.vidame.Activities.BloodPressureActivity has leaked IntentReceiver com.vidame.HelperClasses.Bluetooth$mPairReceiver@37341ff5 that was originally registered here. Are you missing a call to unregisterReceiver()?
    at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:904)
    at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:705)
    at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1685)
    at android.app.ContextImpl.registerReceiver(ContextImpl.java:1665)
    at android.app.ContextImpl.registerReceiver(ContextImpl.java:1659)
    at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:495)
    at com.vidame.HelperClasses.Bluetooth.registerBluetoothBroadcast(Bluetooth.java:83)
    at com.vidame.Activities.BloodPressureActivity$2.onClick(BloodPressureActivity.java:119)
    at android.view.View.performClick(View.java:4789)
    at android.view.View$PerformClick.run(View.java:19881)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5292)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)

我在 Bluetooth.java 类中有我的broadcast receiver 方法以及我在我的应用程序中使用的其他有用方法,并在BloodPressureActivity 中调用它。下面我有这两个类的代码

这是我在BloodPressureActivity注册接收器的地方

devices_list.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            bluetooth.registerBluetoothBroadcast(BloodPressureActivity.this, mAdapter, list, mProgressDlg, mListView);
            device_find.setVisibility(View.GONE);
            devices_list.setVisibility(View.GONE);
            list_view.setVisibility(View.VISIBLE);
            bluetooth.bAdapter().startDiscovery();
        }
    });

我在我的 onDestroy() 和 onStop() 中取消注册

@Override
public void onDestroy() {
    bluetooth.unRegisterReceiver();
    super.onDestroy();
}

@Override
protected void onStop() {
    bluetooth.unRegisterReceiver();
    super.onStop();
}

现在在 Bluetooth.class 我的广播接收器中

 public void registerBluetoothBroadcast (Activity parent, DeviceListAdapter mAdapter, ArrayList<BluetoothDevice> list, ProgressDialog mProgressDlg, ListView mListView){
    this.activity=parent;
    this.mAdapter=mAdapter;
    this.list=list;
    this.mProgressDlg=mProgressDlg;
    this.mListView=mListView;

    IntentFilter filter = new IntentFilter();
    filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
    filter.addAction(BluetoothDevice.ACTION_FOUND);
    filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
    filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
    //filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
    activity.registerReceiver(mPairReceiver, filter);
}


public final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
            final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
            final int prevState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.ERROR);

            if (state == BluetoothDevice.BOND_BONDED && prevState == BluetoothDevice.BOND_BONDING) {
                ShowMessage("Paired");
            } else if (state == BluetoothDevice.BOND_NONE && prevState == BluetoothDevice.BOND_BONDED){
                ShowMessage("Unpaired");
            }
            mAdapter.notifyDataSetChanged();
        }else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
            list = new ArrayList<>();
            mProgressDlg.show();
        } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
            mProgressDlg.dismiss();
            showDevicesList(list);
        } else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            list.add(device);
            ShowMessage("Found device " + device.getName());
        }
    }
};

public void unRegisterReceiver(){
    if(mPairReceiver!=null){
        LocalBroadcastManager.getInstance(activity).unregisterReceiver(mPairReceiver);
    }
}

对于未注册的接收器,我有什么遗漏吗?

【问题讨论】:

  • 在取消注册时,您需要传递上下文,并使用该上下文取消注册。 bluetooth.unRegisterReceiver(this);
  • 删除onStop 函数。您的接收器未注册两次。
  • 当我像这样创建 bluetooth.setActivity(BloodPressureActivity.this); 时,我在 Bluetooth.class 中传递了我的活动上下文。这是我注销蓝牙类中LocalBroadcastManager.getInstance(activity).unregisterReceiver(mPairReceiver);的活动值
  • 看看这个SO question,可能问题和你的差不多
  • ...如果这没有帮助:按钮单击的频率。即您多久注册一次接收者?如果您单击三次并取消注册两次,那么这可能是错误的解释。另一个想法:如果你让接收器静止会发生什么?见this blog

标签: java android bluetooth broadcastreceiver android-broadcastreceiver


【解决方案1】:

您在onDestroy()onStop() 中注销了两次。 如果您在 onCreate 方法中注册广播,则必须在 onDestroy 中取消注册,如果您在 onStart 中注册,则必须在 onStop 中取消注册。 在您的情况下,您在 clickListener 中注册广播,因此如果用户没有单击此按钮,则广播未注册,之后您将尝试取消注册。因此,如果广播已注册,您必须进行测试。 我建议您添加一个布尔属性,当用户单击此按钮时,您将此属性设置为true,一旦您进入onDestroy,您将在此布尔值上进行测试,如果它是真的,则取消注册您的广播。

devices_list.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            bluetooth.registerBluetoothBroadcast(BloodPressureActivity.this, mAdapter, list, mProgressDlg, mListView);
            registred = true;
            device_find.setVisibility(View.GONE);
            devices_list.setVisibility(View.GONE);
            list_view.setVisibility(View.VISIBLE);
            bluetooth.bAdapter().startDiscovery();
        }
    });

onDestroy{
...//your code
if(registred){
unregisterBroadcast(your broadcast);
}

}

【讨论】:

  • 仍然给我同样的错误!在取消注册接收器之前,我已经完成了 onDestroy 和 onPause 的检查,并在再次注册之前完成了 onResume 的检查。
猜你喜欢
  • 1970-01-01
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多