【问题标题】:Broadcast received twice收到两次广播
【发布时间】:2012-09-16 16:03:58
【问题描述】:

我正在使用本地广播让我的服务知道 AsyncTask 已完成其工作,但我有一个小问题:广播仅发送一次(它由仅在启动应用程序时调用的函数创建) 但我收到了两次。

简化代码:

@Override
protected void onPostExecute(HttpResponse result) {
    LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(getBaseContext());
    localBroadcastManager.sendBroadcast(new Intent(getString(R.string.bc_CONNECTED)));
}

在服务中:

private BroadcastReceiver connectedBroadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(getString(R.string.app_tag), "broadcast received !!");
    }
};

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    LocalBroadcastManager.getInstance(this).registerReceiver(connectedBroadcastReceiver, new IntentFilter(getString(R.string.bc_CONNECTED)));
    return START_STICKY;
}

有没有人遇到过这种奇怪的行为?

【问题讨论】:

    标签: android service broadcastreceiver


    【解决方案1】:

    我遇到了同样的问题,问题是我在 onCreate 方法和 onResume 方法中注册了接收器。从onCreate中删除问题就解决了。

    【讨论】:

    • 谢谢,这是我的问题。
    • 这是否也适用于 BroadcastReceiver?使用新的 SDK 版本 (26) 现在我们必须手动注册接收器。我想知道两次调用 registerReceiver 方法是否安全?由于我的应用程序的工作方式,我需要确保接收器在不同的情况下注册,但是,由于不存在“isReceiverRegistered”方法,唯一的方法是简单地注册接收器,但恐怕我可能会注册两次并收到两次消息。
    【解决方案2】:

    在响应广播之前,您应该始终检查意图操作。

    public void onReceive(Context context, Intent intent){
          if(intent.getAction() != null && intent.getAction().equals(getString(R.string.bc_CONNECTED))){
          Log.d(getString(R.string.app_tag), "broadcast received !!");
     }
    }
    

    检查documentation。它说您可能会收到虚假电话。所以总是检查行动

    registerReceiver(BroadcastReceiver, IntentFilter) 和应用程序清单不保证是 独家的。它们是操作系统有关如何查找的提示 合适的收件人。发件人可以强制发送到 特定收件人,绕过过滤器解析。为此原因, onReceive() 实现应仅响应已知操作, 忽略他们可能收到的任何意外 Intent。

    【讨论】:

    • Arg,我认为我的 IntentFilter 会保护我免受虚假调用,因为它包含我的包名称,但可能是这种情况。我将重现该问题以验证其来源。谢谢!
    • @nandeesh if(intent.getAction() != null && intent.getAction().equals(getString(R.string.bc_CONNECTED))) 和 if(intent.getAction( ).equals(getString(R.string.bc_CONNECTED)))?
    • @Hissain 只是一些 NPE 保护。
    • R.string.bc_CONNECTED 的值是多少?
    【解决方案3】:

    我遇到了这个问题,因为我注册了两次,因为我有两个意图过滤器。所以系统两次传递了相同的意图。

      LocalBroadcastManager.getInstance(this).registerReceiver(mLocalReceiver,intentFilterNews);
      LocalBroadcastManager.getInstance(this).registerReceiver(mLocalReceiver,intentFilterWeather);
    

    【讨论】:

      【解决方案4】:

      退出应用程序时是否取消注册接收器?否则,您会在每个应用程序中启动另一个注册的接收器。或者,您必须在注册之前检查接收方是否已在之前的应用调用中注册过。

      【讨论】:

        【解决方案5】:

        确保在任何组件(Activity, Fragment, Service 等...)的onCreate 方法中注册BroadcastReceiver,而不是onResumeonViewCreated(如果是fragmnet)

        例如

        val receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                Log.d("TAGGg",intent?.getBooleanExtra("ext", false).toString())
            }
        }
        
        // On Create method of component
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            LocalBroadcastManager.getInstance(requireActivity()).registerReceiver(receiver, IntentFilter("test-event"))
        }
        

        还要确保在onStop()onDestroy() 中注销接收器

        LocalBroadcastManager.getInstance(requireActivity()).unregisterReceiver(receiver)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-09-27
          • 2017-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-21
          • 1970-01-01
          相关资源
          最近更新 更多