Bagaimana cara menggunakan LocalBroadcastManager?

452

Bagaimana cara menggunakan / mencari LocalBroadcastManagerseperti yang dijelaskan dalam google docs dan Service broadcast doc ?

Saya sudah mencoba google, tetapi tidak ada kode untuk memulai?

Dokumen mengatakan bahwa saya harus menggunakannya jika saya ingin melakukan siaran internal dengan dalam proses aplikasi saya, tetapi saya tidak tahu di mana mencarinya.

Ada bantuan / komentar?

Pembaruan : Saya tahu cara menggunakan Siaran tetapi tidak tahu cara mendapatkan LocalBroadcastManagertersedia di proyek saya.

waqaslam
sumber
Waqas, sudahkah Anda mendaftarkan penerima dalam manifes. Jika ya, beri tahu saya caranya?
Mudassir
2
Saya rasa Anda tidak perlu mendaftarkan receiver untuk siaran semacam itu dalam manifes, karena jika Anda melakukannya, maka penerima tersebut juga akan mendengarkan siaran global.
waqaslam
2
Benar. Maka ini berarti, saya harus melakukannya dalam kode seperti yang diberikan dalam jawaban di bawah ini; LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("custom-event-name"));
Mudassir
2
LocalBroadcastManagertelah ditinggalkan. Saya mengganti milik saya dengan perpustakaan EventBus yang jauh lebih bagus, imo.
Kris B

Jawaban:

862

Saya tetap akan menjawab ini. Untuk berjaga-jaga jika seseorang membutuhkannya.

ReceiverActivity.java

Aktivitas yang memantau notifikasi untuk acara yang dinamai "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

Aktivitas kedua yang mengirim / menyiarkan notifikasi.

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

Dengan kode di atas, setiap kali tombol R.id.button_senddiklik, Intent disiarkan dan diterima oleh mMessageReceiverdalam ReceiverActivity.

Output debug akan terlihat seperti ini:

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! 
Shiki
sumber
7
Terima kasih. sudah mulai bekerja. tetapi masalah yang saya hadapi adalah untuk mendapatkan di kelas LocalBroadcastManager. Karena ini adalah kelas paket dukungan, jadi saya tidak dapat menggunakannya dalam paket biasa sampai saya menambahkan Compatibility Library dari Android Tools. Setelah ditambahkan, semua berjalan dengan baik.
Bagaimanapun
195
harap dicatat bahwa onDestroy()tidak dijamin dipanggil !!! Anda harus menggunakan onPause()(karena hanya onPause()dijamin) dan onResume()(karena itu cocok untuk onPause())
18446744073709551615
5
Teman-teman, perhatikan apa yang sekarang dikatakan google docs tentang Aktivitas setelah onPause (): Killable = Pre-HONEYCOMB Dimulai dengan Honeycomb, aplikasi tidak dalam status dapat dibunuh sampai onStop () telah kembali.
18446744073709551615
59
onDestroy()tidak masalah Kasus di mana itu tidak dipanggil adalah ketika aplikasi terbunuh, dan tidak masalah jika Anda tidak membatalkan pendaftaran dalam kasus itu karena bahkan tidak ada daftar penerima terdaftar yang selamat.
zapl
4
@ Selvin Saya harap Anda sadar bahwa Anda dapat membuat BroadcastReciever direferensikan dengan lemah ke aktivitas penerima dan membuatnya membatalkan pendaftaran sendiri jika sudah yatim piatu. Anda tidak perlu membatalkan registrasi di onPause, onDestroy baik-baik saja selama Anda tidak menggunakan BroadcastReceiver Anda untuk menjaga aktivitas Anda dalam RAM. Contoh Anda menunjukkan praktik buruk dengan kelas dalam bocor itu kelas luar, itu tidak unik untuk BroadcastReceiver dan merupakan sesuatu yang selalu harus dijaga oleh programmer. Sedangkan untuk memodifikasi GUI, Anda dapat menyimpan status ketika aktivitas dilanjutkan, Anda tidak perlu memodifikasi GUI.
JohanShogun
133

Saya lebih suka menjawab secara komprehensif.

  1. LocalbroadcastManager termasuk dalam Android 3.0 dan di atasnya sehingga Anda harus menggunakan perpustakaan dukungan v4 untuk rilis awal. lihat instruksi di sini

  2. Buat penerima siaran:

    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. Daftarkan penerima Anda di onResume aktivitas seperti:

    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. batalkan pendaftaran penerima di onPause:

    protected void onPause() {
      super.onPause();
      LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
    }
    
  5. Sekarang setiap kali siaran lokal dikirim dari aktivitas atau layanan aplikasi, onRiveive on onNotice akan dipanggil :).

Sunting: Anda dapat membaca tutorial lengkap di sini LocalBroadcastManager: Pengalihan pesan aplikasi intra

SohailAziz
sumber
15
+1. jika Penerima Siaran Anda berada dalam sebuah fragmen, daftarkan menggunakan LocalBroadcastManager.getInstance(getActivity()).registerReceiver(onNotice);dan LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(onNotice);
batalkan
3
Apakah Anda yakin LocalBroadcastManager termasuk dalam Android 3.0 dan lebih tinggi? Tidak dapat menemukannya di mana pun kecuali dukungan lib
mente
5
anehnya, LBM hanya termasuk dalam perpustakaan dukungan.
Jeffrey Blattman
1
super.onPause () harus menjadi pernyataan terakhir saat menimpa metode onPause. Batalkan registrasi sebelum super.onPause untuk menghindari bug yang tidak dapat diprediksi
Thupten
2
Saya yakin Anda mungkin ingin memindahkan siklus hidup Anda onStopkarena di Android API 24+ dengan "Multi-Window / Split-View" (diaktifkan secara default pada API 26+ affaicr), aktivitas yang tidak berinteraksi dengan berada dalam keadaan jeda. Sumber: developer.android.com/guide/topics/ui/…
Martin Marconcini
45

Pada saat Menerima:

  • Pertama, daftarkan Penerima Siaran Lokal
  • Kemudian menangani data maksud masuk di 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 
              }
          }
      };
    

Di Akhir Pengiriman:

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

   LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
waqas ali
sumber
Dalam kasus saya hanya ketika saya menetapkan tindakan dengan niat saat mengirim karya siaran metode onReceive () tidak pernah disebut ...
Akash Bisariya
27

Di Eclipse, akhirnya saya harus menambahkan Perpustakaan Kompatibilitas / Dukungan dengan mengklik kanan proyek saya dan memilih:

Android Tools -> Add Support Library

Setelah ditambahkan, maka saya bisa menggunakan LocalBroadcastManagerkelas dalam kode saya.


Perpustakaan Kompatibilitas Android

waqaslam
sumber
12

Bagaimana cara mengubah siaran global Anda ke LocalBroadcast

1) Buat Mesin Virtual

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);

2) Untuk mendaftar BroadcastReceiver

Menggantikan

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

Dengan

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

3) Untuk mengirim pesan siaran

Menggantikan

sendBroadcast(intent);

Dengan

localBroadcastManager.sendBroadcast(intent);

4) Untuk membatalkan pendaftaran pesan siaran

Menggantikan

unregisterReceiver(mybroadcast);

Dengan

localBroadcastManager.unregisterReceiver(mybroadcast);
Rohit Singh
sumber
Bagaimana saya bisa mendaftar beberapa IntentFilter ??
Parikshit Chalke
@ParikshitChalke: tautan
XMAN
12

manajer siaran lokal sudah ditinggalkan, gunakan implementasi dari pola yang dapat diamati sebagai gantinya.

androidx.localbroadcastmanager sedang tidak digunakan dalam versi 1.1.0

Alasan

LocalBroadcastManageradalah bus peristiwa di seluruh aplikasi dan mencakup pelanggaran lapisan di aplikasi Anda; komponen apa pun dapat mendengarkan acara dari komponen lain mana pun. Ini mewarisi batasan use-case yang tidak perlu dari sistem BroadcastManager; pengembang harus menggunakan Intent meskipun objek hanya hidup dalam satu proses dan tidak pernah meninggalkannya. Untuk alasan yang sama, itu tidak mengikuti BroadcastManager bijaksana.

Ini menambah pengalaman pengembang yang membingungkan.

Penggantian

Anda dapat mengganti penggunaan LocalBroadcastManagerdengan implementasi lain dari pola yang dapat diamati. Tergantung pada kasus penggunaan Anda, opsi yang sesuai mungkin LiveDataatau aliran reaktif.

Keuntungan dari LiveData

Anda dapat memperluas LiveDataobjek menggunakan pola tunggal untuk membungkus layanan sistem sehingga mereka dapat dibagikan di aplikasi Anda. The LiveDataobjek menghubungkan ke layanan sistem sekali, dan kemudian pengamat setiap yang perlu sumber daya hanya dapat menonton LiveDataobjek.

 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()Metode melewati fragmen, yang merupakan contoh dari LifecycleOwner, sebagai argumen pertama. Melakukan hal itu menunjukkan bahwa pengamat ini terikat pada Lifecycleobjek yang terkait dengan pemilik, yang berarti:

  • Jika objek Siklus Hidup tidak dalam keadaan aktif, maka pengamat tidak dipanggil bahkan jika nilainya berubah.

  • Setelah objek Siklus Hidup dihancurkan, pengamat akan dihapus secara otomatis

Fakta bahwa LiveDataobjek sadar siklus berarti Anda dapat membaginya di antara beberapa aktivitas, fragmen, dan layanan.

Sayang
sumber
1
Anda benar tentang membocorkan konteks ke seluruh dunia, tetapi saya ingin tahu apa yang akan menjadi pengganti yang cocok ketika saya ingin berkomunikasi dari layanan latar depan yang berjalan bahkan tanpa aktivitas, tetapi ketika aktivitas masuk, mereka perlu berkomunikasi?
ateebahmed
1
Buat kelas singleton dengan objek LiveData dan posting data Anda dari layanan. Setelah aktivitas diluncurkan, aktivitas dapat dengan mudah mengamati LiveData tanpa membahayakan. misal: MyServiceData.getInstance (). getMyData (). amati ...
Darish
3
Saya akan merindukan LocalBroadcastManager. Jika itu membingungkan para pengembang di Google, mungkin mereka perlu menghentikan hal-hal rekayasa berlebihan?
AFD
@ Darish Apakah kelas singleton ini sama dengan menyimpannya di objek Aplikasi? Mengapa negara global semacam ini dalam kasus ini tidak dianggap praktik buruk?
xuiqzy
6

Ketika Anda akan bermain cukup dengan LocalBroadcastReceiver saya akan menyarankan Anda untuk mencoba EventBus Green Robot - Anda pasti akan menyadari perbedaan dan kegunaannya dibandingkan dengan LBR. Lebih sedikit kode, dapat disesuaikan tentang utas penerima (UI / Bg), memeriksa ketersediaan penerima, acara tempel, acara dapat digunakan sebagai pengiriman data dll.

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

Dengan mendeklarasikan satu di file AndroidManifest.xml Anda dengan tag (juga disebut statis)

<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>

Anda akan melihat bahwa penerima siaran yang dinyatakan di atas memiliki properti yang diekspor = "true". Atribut ini memberi tahu penerima bahwa ia dapat menerima siaran dari luar lingkup aplikasi.
2. Atau secara dinamis dengan mendaftarkan sebuah instance dengan registerReceiver (apa yang dikenal sebagai konteks terdaftar)

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

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

Ada tiga cara untuk mengirim siaran:
Metode sendOrderedBroadcast, pastikan untuk mengirim siaran hanya ke satu penerima pada satu waktu. Setiap siaran pada gilirannya, meneruskan data ke yang mengikutinya, atau untuk menghentikan penyebaran siaran ke penerima yang mengikuti.
SendBroadcast mirip dengan metode yang disebutkan di atas, dengan satu perbedaan. Semua penerima siaran menerima pesan dan tidak saling bergantung.
Metode LocalBroadcastManager.sendBroadcast hanya mengirimkan siaran ke penerima yang ditentukan di dalam aplikasi Anda dan tidak melebihi ruang lingkup aplikasi Anda.

Seroj Grigoryan
sumber
-4

kita juga bisa menggunakan antarmuka yang sama dengan broadcastManger di sini saya membagikan kode testd untuk broadcastManager tetapi dengan antarmuka.

pertama-tama buat antarmuka seperti:

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

2-ini adalah kelas pertama yang membutuhkan implementasi

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-di sini adalah kelas kedua yang mengimplementasikan antarmuka yang sama yang metode panggilannya secara otomatis

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

jadi dengan pendekatan ini kita bisa menggunakan antarmuka yang berfungsi sama dengan broadcastManager.

padmender singh
sumber