Làm thế nào để sử dụng LocalBroadcastManager?


452

Làm cách nào để sử dụng / định vị LocalBroadcastManagernhư được mô tả trong tài liệu googletài liệu quảng bá dịch vụ ?

Tôi cố gắng để google nó, nhưng không có mã sẵn để bắt đầu với?

Các tài liệu nói rằng tôi nên sử dụng nó nếu tôi muốn phát sóng nội bộ trong quy trình của ứng dụng của mình nhưng tôi không biết tìm nó ở đâu.

Bất kỳ trợ giúp / bình luận?

Cập nhật : Tôi biết cách sử dụng Phát sóng nhưng không biết làm thế nào để có LocalBroadcastManagersẵn trong dự án của mình.


Waqas, bạn đã đăng ký người nhận trong bảng kê khai. Nếu có, xin vui lòng cho tôi biết làm thế nào?
Mudassir

2
Tôi không nghĩ rằng bạn cần phải đăng ký người nhận cho các chương trình phát sóng như vậy trong bản kê khai, bởi vì nếu bạn làm vậy, thì người nhận đó cũng sẽ lắng nghe các chương trình phát sóng toàn cầu.
waqaslam

2
Thật. Sau đó, điều này có nghĩa là, tôi phải thực hiện nó trong mã như được đưa ra trong câu trả lời dưới đây; LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("custom-event-name"));
Mudassir

2
LocalBroadcastManagerđã bị phản đối Tôi đã thay thế tôi bằng thư viện EventBus đẹp hơn nhiều, imo.
Kris B

Câu trả lời:


861

Tôi sẽ trả lời điều này. Chỉ trong trường hợp ai đó cần nó.

Người nhậnActivity.java

Một hoạt động theo dõi các thông báo cho sự kiện được đặt tên "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();
}

Người gửiActivity.java

Hoạt động thứ hai gửi / phát thông báo.

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

Với đoạn mã trên, mỗi khi nút R.id.button_sendđược nhấn vào, Intent được phát sóng và nhận được bởi mMessageReceivertrong ReceiverActivity.

Đầu ra gỡ lỗi sẽ trông như thế này:

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! 

7
cảm ơn. làm cho nó hoạt động rồi nhưng vấn đề tôi gặp phải là giữ lớp LocalBroadcastManager. Vì là lớp gói hỗ trợ, vì vậy tôi không thể sử dụng nó trong gói thông thường cho đến khi tôi thêm Thư viện tương thích từ Công cụ Android. Một khi nó được thêm vào, tất cả đều ổn. dù sao, cảm ơn vì câu trả lời
waqaslam

195
xin lưu ý rằng onDestroy()không được đảm bảo để được gọi !!! Bạn phải sử dụng onPause()(vì chỉ onPause()được bảo đảm) và onResume()(vì đó là trận đấu cho onPause())
18446744073709551615

5
Mọi người, lưu ý những gì các tài liệu google hiện nói về một Hoạt động sau khi onPause (): Killable = Pre-HONEYCOMB Bắt đầu với Honeycomb, một ứng dụng không ở trạng thái có thể hủy được cho đến khi onStop () của nó trở lại.
18446744073709551615

59
onDestroy()không có vấn đề gì. Trường hợp không được gọi là khi ứng dụng bị giết và không thành vấn đề nếu bạn không đăng ký trong trường hợp đó vì ngay cả danh sách người nhận đã đăng ký vẫn tồn tại.
zapl

4
@Selvin Tôi hy vọng bạn biết rằng bạn có thể làm cho BroadcastReciever được tham chiếu yếu đến hoạt động thu và làm cho nó không được đăng ký nếu nó bị mồ côi. Bạn không cần hủy đăng ký nó trong onPause, onDestroy vẫn ổn miễn là bạn không sử dụng BroadcastReceiver để duy trì hoạt động của mình trong RAM. Ví dụ của bạn cho thấy một thực tiễn tồi tệ với một lớp bên trong bị rò rỉ lớp bên ngoài, nó không phải là duy nhất cho BroadcastReceiver và là thứ mà các lập trình viên luôn phải đề phòng. Đối với việc sửa đổi GUI, bạn có thể lưu trữ trạng thái khi hoạt động được tiếp tục, bạn không phải sửa đổi GUI.
JohanShogun

133

Tôi muốn trả lời một cách toàn diện.

  1. LocalbroadcastManager có trong Android 3.0 trở lên, do đó bạn phải sử dụng thư viện hỗ trợ v4 để phát hành sớm. xem hướng dẫn tại đây

  2. Tạo một máy thu phát sóng:

    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 !");
    
        }
    };
  3. Đăng ký người nhận của bạn trong onResume của hoạt động như:

    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.
  4. unRegister nhận trong onPause:

    protected void onPause() {
      super.onPause();
      LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
    }
  5. Bây giờ, bất cứ khi nào một localbroadcast được gửi từ hoạt động hoặc dịch vụ của ứng dụng, onReceive của onNotice sẽ được gọi :).

Chỉnh sửa: Bạn có thể đọc hướng dẫn đầy đủ tại đây LocalBroadcastManager: Thông báo ứng dụng Intra đi qua


15
+1. nếu Bộ thu phát của bạn bị phân mảnh, hãy đăng ký bằng cách sử dụng LocalBroadcastManager.getInstance(getActivity()).registerReceiver(onNotice);và hủy đăng ký nó bằng cách sử dụngLocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(onNotice);
PeteH

3
Bạn có chắc chắn rằng LocalBroadcastManager được tích hợp trong Android 3.0 trở lên không? Không thể tìm thấy nó ở bất cứ đâu ngoại trừ hỗ trợ lib
mente

5
Thật kỳ lạ, LBM chỉ được bao gồm trong thư viện hỗ trợ.
Jeffrey Blattman

1
super.onPause () phải là câu lệnh cuối cùng khi ghi đè phương thức onPause. Hủy đăng ký trước super.onPin để tránh lỗi không thể đoán trước
Thupten

2
Tôi tin rằng bạn có thể muốn chuyển vòng đời của mình sang onStopvì trong API Android 24+ với Đa cửa sổ / Chia-Xem-Chế độ (được bật theo mặc định trên API 26+ affomsr), hoạt động không được tương tác ở trạng thái tạm dừng. Nguồn: developer.android.com/guide/topics/ui/ từ
Martin Marconcini

45

Khi nhận được kết thúc:

  • Đăng ký đầu tiên Người nhận LocalBroadcast
  • Sau đó xử lý dữ liệu mục đích đến trong 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 
              }
          }
      };

Về việc kết thúc:

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

   LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

Trong trường hợp của tôi chỉ khi tôi đặt hành động theo ý định khi gửi các tác phẩm quảng bá thì phương thức onReceive () không bao giờ được gọi ...
Akash Bisariya

27

Trong Eclipse, cuối cùng tôi đã phải thêm Thư viện tương thích / hỗ trợ bằng cách nhấn chuột phải vào dự án của mình và chọn:

Android Tools -> Add Support Library

Khi nó được thêm vào, sau đó tôi có thể sử dụng LocalBroadcastManagerlớp trong mã của mình.


Thư viện tương thích Android


12

Làm cách nào để thay đổi chương trình phát sóng toàn cầu của bạn sang LocalBroadcast

1) Tạo sơ thẩm

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);

2) Để đăng ký BroadcastReceiver

Thay thế

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

Với

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

3) Để gửi tin nhắn quảng bá

Thay thế

sendBroadcast(intent);

Với

localBroadcastManager.sendBroadcast(intent);

4) Đối với tin nhắn quảng bá không đăng ký

Thay thế

unregisterReceiver(mybroadcast);

Với

localBroadcastManager.unregisterReceiver(mybroadcast);

Làm thế nào tôi có thể đăng ký nhiều IntentFilter ??
Parikshit Chalke

@ParikshitChalke: link
Xman

12

localbroadcastmanager không được dùng nữa, thay vào đó hãy sử dụng các mẫu có thể quan sát được.

androidx.localbroadcastmanager đang bị phản đối trong phiên bản 1.1.0

Lý do

LocalBroadcastManagerlà một xe buýt sự kiện toàn ứng dụng và xử lý các vi phạm lớp trong ứng dụng của bạn; bất kỳ thành phần nào cũng có thể lắng nghe các sự kiện từ bất kỳ thành phần nào khác. Nó kế thừa các giới hạn trường hợp sử dụng không cần thiết của BroadcastManager hệ thống; các nhà phát triển phải sử dụng Ý định mặc dù các đối tượng chỉ sống trong một quy trình và không bao giờ rời khỏi nó. Vì lý do tương tự, nó không tuân theo BroadcastManager có tính năng.

Những điều này thêm vào một kinh nghiệm phát triển khó hiểu.

Thay thế

Bạn có thể thay thế việc sử dụng LocalBroadcastManagerbằng các triển khai khác của mẫu có thể quan sát được. Tùy thuộc vào trường hợp sử dụng của bạn, các tùy chọn phù hợp có thể LiveDatahoặc các luồng phản ứng.

Lợi thế của LiveData

Bạn có thể mở rộng một LiveDatađối tượng bằng cách sử dụng mẫu singleton để bọc các dịch vụ hệ thống để chúng có thể được chia sẻ trong ứng dụng của bạn. Đối LiveDatatượng kết nối với dịch vụ hệ thống một lần, và sau đó bất kỳ người quan sát nào cần tài nguyên chỉ có thể xem LiveDatađối tượng.

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

Các observe()phương pháp vượt qua đoạn, đó là một thể hiện của LifecycleOwner, như là đối số đầu tiên. Làm như vậy biểu thị rằng người quan sát này bị ràng buộc với Lifecycleđối tượng được liên kết với chủ sở hữu, có nghĩa là:

  • Nếu đối tượng Vòng đời không ở trạng thái hoạt động, thì người quan sát sẽ không được gọi ngay cả khi giá trị thay đổi.

  • Sau khi đối tượng Vòng đời bị hủy, người quan sát sẽ tự động bị xóa

Thực tế là LiveDatacác đối tượng nhận thức được vòng đời có nghĩa là bạn có thể chia sẻ chúng giữa nhiều hoạt động, đoạn và dịch vụ.


1
bạn đúng về việc rò rỉ bối cảnh ra toàn thế giới, nhưng tôi muốn biết điều gì sẽ là sự thay thế phù hợp khi tôi muốn giao tiếp từ một dịch vụ tiền cảnh đang chạy ngay cả khi không có hoạt động, nhưng khi hoạt động đến, họ cần giao tiếp?
ăn tối

1
Tạo một lớp đơn với một đối tượng LiveData và đăng dữ liệu của bạn từ dịch vụ. Khi hoạt động khởi chạy, hoạt động có thể dễ dàng quan sát LiveData mà không gây hại. ví dụ: MyServiceData.getInstance (). getMyData (). quan sát ...
Darish

3
Tôi sẽ bỏ lỡ LocalBroadcastManager. Nếu nó gây nhầm lẫn cho các nhà phát triển tại Google, có lẽ họ cần dừng những thứ quá kỹ thuật?
AFD

@Darish Lớp singleton này có tương đương với việc lưu trữ nó trong đối tượng Ứng dụng không? Tại sao loại nhà nước toàn cầu này trong những trường hợp này không được coi là thực hành xấu?
xuiqzy

6

Khi bạn chơi đủ với LocalBroadcastReceiver, tôi sẽ đề nghị bạn dùng thử EventBus của Green Robot - bạn chắc chắn sẽ nhận ra sự khác biệt và hữu ích của nó so với LBR. Ít mã hơn, có thể tùy chỉnh về luồng của người nhận (UI / Bg), kiểm tra tính khả dụng của người nhận, các sự kiện dính, sự kiện có thể được sử dụng làm phân phối dữ liệu, v.v.



0
enter code here if (createSuccses){
                        val userDataChange=Intent(BRODCAST_USER_DATA_CHANGE)
                        LocalBroadcastManager.getInstance(this).sendBroadcast(
                            userDataChange
                        )
                        enableSpinner(false)
                        finish()

0

Bằng cách khai báo một trong tệp AndroidManifest.xml của bạn bằng thẻ (còn được gọi là tĩnh)

<receiver android:name=".YourBrodcastReceiverClass"  android:exported="true">
<intent-filter>
    <!-- The actions you wish to listen to, below is an example -->
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>

Bạn sẽ nhận thấy rằng bộ thu phát được khai báo ở trên có thuộc tính là export =. Thuộc tính này cho người nhận biết rằng nó có thể nhận các chương trình phát sóng từ bên ngoài phạm vi của ứng dụng.
2. Hoặc tự động bằng cách đăng ký một cá thể với registerReceiver (được gọi là bối cảnh đã đăng ký)

public abstract Intent registerReceiver (BroadcastReceiver receiver, 
            IntentFilter filter);

public void onReceive(Context context, Intent intent) {
//Implement your logic here
}

Có ba cách để gửi truyền phát:
Phương thức sendOrderedBroadcast, đảm bảo gửi truyền phát đến chỉ một người nhận tại một thời điểm. Mỗi lần phát có thể lần lượt truyền dữ liệu cho người theo dõi hoặc dừng việc truyền phát cho người nhận theo dõi.
SendBroadcast tương tự như phương thức được đề cập ở trên, với một điểm khác biệt. Tất cả các máy thu phát sóng nhận được tin nhắn và không phụ thuộc vào nhau.
Phương thức LocalBroadcastManager.sendBroadcast chỉ gửi truyền phát đến các máy thu được xác định trong ứng dụng của bạn và không vượt quá phạm vi ứng dụng của bạn.


-4

chúng ta cũng có thể sử dụng giao diện giống như BroadcastManger ở đây. Tôi đang chia sẻ mã testd cho BroadcastManager nhưng bằng giao diện.

đầu tiên tạo một giao diện như:

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

2-đây là lớp đầu tiên cần thực hiện

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-đây là lớp thứ hai thực hiện cùng một giao diện có phương thức gọi tự động

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

Vì vậy, bằng cách tiếp cận này, chúng ta có thể sử dụng giao diện hoạt động giống như BroadcastManager.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.