如何使用LocalBroadcastManager?

waq*_*lam 440 android broadcastreceiver

LocalBroadcastManager谷歌文档服务广播文档中所述如何使用/定位?

我试图谷歌它,但没有可用的代码开始?

文件说如果我想在我的应用程序进程内部进行广播,我应该使用它,但我不知道在哪里寻找这个.

任何帮助/评论?

更新:我知道如何使用广播,但不知道如何LocalBroadcastManager在我的项目中使用.

Shi*_*iki 835

无论如何我会回答这个问题.以防有人需要它.

ReceiverActivity.java

监视名为的事件的通知的活动"custom-event-name".

@Override
public void onCreate(Bundle savedInstanceState) {

  ...

  // Register to receive messages.
  // We are registering an observer (mMessageReceiver) to receive Intents
  // with actions named "custom-event-name".
  LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
      new IntentFilter("custom-event-name"));
}

// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
    // Get extra data included in the Intent
    String message = intent.getStringExtra("message");
    Log.d("receiver", "Got message: " + message);
  }
};

@Override
protected void onDestroy() {
  // Unregister since the activity is about to be closed.
  LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
  super.onDestroy();
}
Run Code Online (Sandbox Code Playgroud)

SenderActivity.java

发送/广播通知的第二个活动.

@Override
public void onCreate(Bundle savedInstanceState) {

  ...

  // Every time a button is clicked, we want to broadcast a notification.
  findViewById(R.id.button_send).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      sendMessage();
    }
  });
}

// Send an Intent with an action named "custom-event-name". The Intent sent should 
// be received by the ReceiverActivity.
private void sendMessage() {
  Log.d("sender", "Broadcasting message");
  Intent intent = new Intent("custom-event-name");
  // You can also include some extra data.
  intent.putExtra("message", "This is my message!");
  LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
Run Code Online (Sandbox Code Playgroud)

使用上面的代码,每次R.id.button_send单击按钮时,都会广播一个Intent并由mMessageReceiverin 接收ReceiverActivity.

调试输出应如下所示:

01-16 10:35:42.413: D/sender(356): Broadcasting message
01-16 10:35:42.421: D/receiver(356): Got message: This is my message! 
Run Code Online (Sandbox Code Playgroud)

  • 请注意**'onDestroy()`不能保证被调用!!!**你必须使用`onPause()`(因为只保证`onPause()`和`onResume()`(因为它是匹配`onPause()`) (191认同)
  • `onDestroy()`没问题.未被调用的情况是应用程序被杀死时,如果在这种情况下不注销则无关紧要,因为即使已注册的接收者列表也不存在. (57认同)
  • 谢谢.让它工作了.但我遇到的问题是要抓住LocalBroadcastManager类.由于它是一个支持包类,所以我无法在我的普通包中使用它,直到我从Android Tools添加了兼容性库.一旦添加,一切都很好.无论如何,谢谢你的回答 (7认同)
  • 伙计们,请注意google文档现在对onPause()之后的Activity的说法:Killable = Pre-HONEYCOMB _Starting with Honeycomb,应用程序在其onStop()返回之前不处于killable状态._ (5认同)
  • @Selvin我希望你知道你可以让BroadcastReciever弱引用接收活动,如果它已被孤立,则让它自己取消注册.您不需要在onPause中注销它,只要您不使用BroadcastReceiver将活动保存在RAM中,onDestroy就可以了.你的例子显示了一个不好的做法,内部类泄漏了它的外部类,它并不是BroadcastReceiver独有的,而且是程序员总是要防范的.至于修改GUI,您可以存储恢复活动的状态,您不必修改GUI. (4认同)
  • 当然,使用 LocalBroadcastManager 在 Activity 之间进行通信是一个坏主意......最佳实践告诉接收者应该在 onPause 中取消注册,因为在此之后与 UI 的任何交互都没有意义......也将 Activity 引用存储在某个静态类中更长的时间可见是不好的做法(弱引用是可以的,但 LocalBroadcastManager 内部没有使用它们)......结论:**你永远不应该使用 LocalBroadcastManager 在活动之间进行通信** (2认同)

Soh*_*ziz 127

我宁愿全面回答.

  1. LocalbroadcastManager包含在android 3.0及更高版本中,所以你必须使用支持库v4进行早期版本.看这里的说明

  2. 创建广播接收器:

    private BroadcastReceiver onNotice= new BroadcastReceiver() {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            // intent can contain anydata
            Log.d("sohail","onReceive called");
            tv.setText("Broadcast received !");
    
        }
    };
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在onResume中注册您的接收器,例如:

    protected void onResume() {
            super.onResume();
    
            IntentFilter iff= new IntentFilter(MyIntentService.ACTION);
            LocalBroadcastManager.getInstance(this).registerReceiver(onNotice, iff);
        }
    
    //MyIntentService.ACTION is just a public static string defined in MyIntentService.
    
    Run Code Online (Sandbox Code Playgroud)
  4. onPause中的unRegister接收器:

    protected void onPause() {
      super.onPause();
      LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  5. 现在,每当从应用程序的活动或服务发送localbroadcast时,onReceive on onNotice将被调用:).

编辑:您可以在这里阅读完整的教程LocalBroadcastManager:Intra应用程序消息传递

  • +1.如果您的广播接收器位于片段中,请使用`LocalBroadcastManager.getInstance(getActivity())注册它.registerReceiver(onNotice);`并使用`LocalBroadcastManager.getInstance(getActivity())取消注册它.unregisterReceiver(onNotice);` (14认同)
  • 奇怪的是,LBM仅包含在支持库中. (4认同)
  • 你确定LocalBroadcastManager包含在Android 3.0及更高版本中吗?除了支持lib之外无法找到它 (3认同)
  • 我相信您可能希望将生命周期转移到"onStop",因为在Android API 24+中使用"Multi-Window/Split-View"(默认情况下在API 26+ affaicr上启用),未与之交互的活动处于暂停状态州.资料来源:https://developer.android.com/guide/topics/ui/multi-window.html#lifecycle (2认同)
  • @AJW我不会。确实没有理由这样做(我能想到的)。这实际上取决于您的用例。在大多数情况下,考虑到对话框将触发 onPause,onStop/Start 往往会更好,并且可能不希望因为出现对话框而“取消订阅”事物(仅稍后重新订阅)。或者在某些情况下是的,所以......确保这就是你想要的;) (2认同)

waq*_*ali 39

在接收结束时:

  • 首先注册LocalBroadcast Receiver
  • 然后处理onReceive中的传入意图数据.

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
    
          LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
          lbm.registerReceiver(receiver, new IntentFilter("filter_string"));
      }
    
      public BroadcastReceiver receiver = new BroadcastReceiver() {
          @Override
          public void onReceive(Context context, Intent intent) {
              if (intent != null) {
                  String str = intent.getStringExtra("key");
                  // get all your data from intent and do what you want 
              }
          }
      };
    
    Run Code Online (Sandbox Code Playgroud)

发送结束时:

   Intent intent = new Intent("filter_string");
   intent.putExtra("key", "My Data");
   // put your all data using put extra 

   LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
Run Code Online (Sandbox Code Playgroud)


waq*_*lam 27

在Eclipse中,最终我必须通过右键单击我的项目并选择以下内容来添加兼容性/支持库:

Android Tools - > Add Support Library

一旦添加,我就可以LocalBroadcastManager在我的代码中使用类.


Android兼容性库


Roh*_*ngh 9

如何将全局广播更改为LocalBroadcast

1)创建实例

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
Run Code Online (Sandbox Code Playgroud)

2)用于注册BroadcastReceiver

更换

registerReceiver(new YourReceiver(),new IntentFilter("YourAction"));
Run Code Online (Sandbox Code Playgroud)

localBroadcastManager.registerReceiver(new YourReceiver(),new IntentFilter("YourAction"));
Run Code Online (Sandbox Code Playgroud)

3)用于发送广播消息

更换

sendBroadcast(intent);
Run Code Online (Sandbox Code Playgroud)

localBroadcastManager.sendBroadcast(intent);
Run Code Online (Sandbox Code Playgroud)

4)取消注册广播消息

更换

unregisterReceiver(mybroadcast);
Run Code Online (Sandbox Code Playgroud)

localBroadcastManager.unregisterReceiver(mybroadcast);
Run Code Online (Sandbox Code Playgroud)


Dar*_*ish 7

androidx.localbroadcastmanager 1.1.0 版中已弃用

原因

LocalBroadcastManager是应用程序范围内的事件总线,在您的应用程序中包含违反层的行为;任何组件都可以侦听来自任何其他组件的事件。它继承了系统BroadcastManager的不必要用例限制;开发人员必须使用Intent,即使对象只存在于一个进程中,也永远不要离开它。出于同样的原因,它不遵循基于功能的BroadcastManager。

这些加在一起使开发人员感到困惑。

替代

您可以将的用法替换LocalBroadcastManager为可观察模式的其他实现。根据您的用例,合适的选项可能是LiveData反应流。

LiveData的优势

您可以LiveData使用单例模式扩展对象以包装系统服务,以便可以在您的应用程序中共享它们。该LiveData对象一次连接到系统服务,然后任何需要资源的观察者都可以监视该LiveData对象。

 public class MyFragment extends Fragment {
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        LiveData<BigDecimal> myPriceListener = ...;
        myPriceListener.observe(this, price -> {
            // Update the UI.
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

observe()方法将作为实例的片段LifecycleOwner作为第一个参数。这样做表示此观察者已绑定到Lifecycle与所有者关联的对象,这意味着:

  • 如果Lifecycle对象未处于活动状态,则即使值更改也不会调用观察者。

  • 生命周期对象销毁后,观察者将自动删除

LiveData对象具有生命周期感知这一事实意味着您可以在多个活动,片段和服务之间共享它们。

  • 我会想念 LocalBroadcastManager 的。如果谷歌的开发人员感到困惑,也许他们需要停止过度设计? (4认同)
  • 创建一个带有 LiveData 对象的单例类,并从服务中发布您的数据。一旦 Activity 启动,Activity 就可以轻松地观察 LiveData,而不会造成任何伤害。例如:MyServiceData.getInstance().getMyData().observe ... (3认同)

Sta*_*tan 6

当您使用 LocalBroadcastReceiver 玩够了时,我建议您尝试一下Green Robot 的 EventBus - 与 LBR 相比,您一定会意识到它的不同之处和实用性。更少的代码,可定制接收者的线程(UI/Bg),检查接收者的可用性,粘性事件,事件可以用作数据传递等。


Sha*_*T D 5

使用的 Kotlin 版本LocalBroadcastManager

请检查以下代码registeringsending消息。receivingbroadcast

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // register broadcast manager
        val localBroadcastManager = LocalBroadcastManager.getInstance(this)
        localBroadcastManager.registerReceiver(receiver, IntentFilter("your_action"))
    }

    // broadcast receiver
    var receiver: BroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if (intent != null) {
                val str = intent.getStringExtra("key")
                
            }
        }
    }

    /**
     * Send broadcast method
     */
    fun sendBroadcast() {
        val intent = Intent("your_action")
        intent.putExtra("key", "Your data")
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }

    override fun onDestroy() {
        // Unregister broadcast
        LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)
        super.onDestroy()
    }

}
Run Code Online (Sandbox Code Playgroud)