How to use LocalBroadcastManager?

后端 未结 13 3191
天命终不由人
天命终不由人 2020-11-21 04:15

How to use/locate LocalBroadcastManager as described in google docs and Service broadcast doc?

I tried to google it, but there is no code available to s

相关标签:
13条回答
  • 2020-11-21 04:53

    localbroadcastmanager is deprecated, use implementations of the observable pattern instead.

    androidx.localbroadcastmanager is being deprecated in version 1.1.0

    Reason

    LocalBroadcastManager is an application-wide event bus and embraces layer violations in your app; any component may listen to events from any other component. It inherits unnecessary use-case limitations of system BroadcastManager; developers have to use Intent even though objects live in only one process and never leave it. For this same reason, it doesn’t follow feature-wise BroadcastManager .

    These add up to a confusing developer experience.

    Replacement

    You can replace usage of LocalBroadcastManager with other implementations of the observable pattern. Depending on your use case, suitable options may be LiveData or reactive streams.

    Advantage of LiveData

    You can extend a LiveData object using the singleton pattern to wrap system services so that they can be shared in your app. The LiveData object connects to the system service once, and then any observer that needs the resource can just watch the LiveData object.

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

    The observe() method passes the fragment, which is an instance of LifecycleOwner, as the first argument. Doing so denotes that this observer is bound to the Lifecycle object associated with the owner, meaning:

    • If the Lifecycle object is not in an active state, then the observer isn't called even if the value changes.

    • After the Lifecycle object is destroyed, the observer is automatically removed

    The fact that LiveData objects are lifecycle-aware means that you can share them between multiple activities, fragments, and services.

    0 讨论(0)
  • 2020-11-21 04:53

    How to change your global broadcast to LocalBroadcast

    1) Create Instance

    LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
    

    2) For registering BroadcastReceiver

    Replace

    registerReceiver(new YourReceiver(),new IntentFilter("YourAction"));
    

    With

    localBroadcastManager.registerReceiver(new YourReceiver(),new IntentFilter("YourAction"));
    

    3) For sending broadcast message

    Replace

    sendBroadcast(intent);
    

    With

    localBroadcastManager.sendBroadcast(intent);
    

    4) For unregistering broadcast message

    Replace

    unregisterReceiver(mybroadcast);
    

    With

    localBroadcastManager.unregisterReceiver(mybroadcast);
    
    0 讨论(0)
  • 2020-11-21 04:53

    I am an iOS dev, so I made a solution similar to NotificationCenter:

    object NotificationCenter {
        var observers: MutableMap<String, MutableList<NotificationObserver>> = mutableMapOf()
    
        fun addObserver(observer: NotificationObserver, notificationName: NotificationName) {
            var os = observers[notificationName.value]
            if (os == null) {
                os = mutableListOf<NotificationObserver>()
                observers[notificationName.value] = os
            }
            os.add(observer)
        }
    
        fun removeObserver(observer: NotificationObserver, notificationName: NotificationName) {
            val os = observers[notificationName.value]
            if (os != null) {
                os.remove(observer)
            }
        }
    
        fun removeObserver(observer:NotificationObserver) {
            observers.forEach { name, mutableList ->
                if (mutableList.contains(observer)) {
                    mutableList.remove(observer)
                }
            }
        }
    
        fun postNotification(notificationName: NotificationName, obj: Any?) {
            val os = observers[notificationName.value]
            if (os != null) {
                os.forEach {observer ->
                    observer.onNotification(notificationName,obj)
                }
            }
        }
    }
    
    interface NotificationObserver {
        fun onNotification(name: NotificationName,obj:Any?)
    }
    
    enum class NotificationName(val value: String) {
        onPlayerStatReceived("on player stat received"),
        ...
    }
    

    Some class that want to observe notification must conform to observer protocol:

    class MainActivity : AppCompatActivity(), NotificationObserver {
        override fun onCreate(savedInstanceState: Bundle?) {
            ...
            NotificationCenter.addObserver(this,NotificationName.onPlayerStatReceived)
        }
        override fun onDestroy() {
            ...
            super.onDestroy()
            NotificationCenter.removeObserver(this)
        }
    
        ...
        override fun onNotification(name: NotificationName, obj: Any?) {
            when (name) {
                NotificationName.onPlayerStatReceived -> {
                    Log.d(tag, "onPlayerStatReceived")
                }
                else -> Log.e(tag, "Notification not handled")
            }
        }
    

    Finally, post some notification to observers:

    NotificationCenter.postNotification(NotificationName.onPlayerStatReceived,null)
    
    0 讨论(0)
  • 2020-11-21 04:54

    we can also use interface for same as broadcastManger here i am sharing the testd code for broadcastManager but by interface.

    first make an interface like:

    public interface MyInterface {
         void GetName(String name);
    }
    

    2-this is the first class that need implementation

    public class First implements MyInterface{
    
        MyInterface interfc;    
        public static void main(String[] args) {
          First f=new First();      
          Second s=new Second();
          f.initIterface(s);
          f.GetName("Paddy");
      }
      private void initIterface(MyInterface interfc){
        this.interfc=interfc;
      }
      public void GetName(String name) {
        System.out.println("first "+name);
        interfc.GetName(name);  
      }
    }
    

    3-here is the the second class that implement the same interface whose method call automatically

    public class Second implements MyInterface{
       public void GetName(String name) {
         System.out.println("Second"+name);
       }
    }
    

    so by this approach we can use the interface functioning same as broadcastManager.

    0 讨论(0)
  • 2020-11-21 04:57

    I'll answer this anyway. Just in case someone needs it.

    ReceiverActivity.java

    An activity that watches for notifications for the event named "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();
    }
    

    SenderActivity.java

    The second activity that sends/broadcasts notifications.

    @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);
    }
    

    With the code above, every time the button R.id.button_send is clicked, an Intent is broadcasted and is received by mMessageReceiver in ReceiverActivity.

    The debug output should look like this:

    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! 
    
    0 讨论(0)
  • 2020-11-21 04:58

    When you'll play enough with LocalBroadcastReceiver I'll suggest you to give Green Robot's EventBus a try - you will definitely realize the difference and usefulness of it compared to LBR. Less code, customizable about receiver's thread (UI/Bg), checking receivers availability, sticky events, events could be used as data delivery etc.

    0 讨论(0)
提交回复
热议问题