LocalBroadcastManagerの使用方法


452

google docsService broadcast docでLocalBroadcastManager説明されているように使用/検索する方法は?

私はそれをグーグルしようとしました、しかし、始めるために利用できるコードがありませんか?

アプリのプロセスで内部でブロードキャストを実行したいのですが、どこを探すべきかわからない場合は、ドキュメントを使用する必要があると記載されています。

ヘルプ/コメントはありますか?

更新:ブロードキャストの使用方法は知っていLocalBroadcastManagerますが、プロジェクトで使用できるようにする方法がわかりません。


Waqas、マニフェストに受信機を登録しましたか。はいの場合は、方法を教えてください。
Mudassir

2
そのようなブロードキャストのレシーバーをマニフェストに登録する必要はないと思います。登録すると、そのレシーバーはグローバルブロードキャストもリッスンします。
waqaslam

2
本当です。次に、これは、以下の答えで示されているように、コードで実行する必要があることを意味します。LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("custom-event-name"));
Mudassir 2012

2
LocalBroadcastManager廃止されました。私は、より良いimoであるEventBusライブラリーに置き換えました。
クリスB

回答:


861

とにかくこれに答えます。誰かがそれを必要とする場合に備えて。

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

SenderActivity.java

通知を送信/ブロードキャストする2番目のアクティビティ。

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

上記のコードでR.id.button_sendは、ボタンがクリックされるたびに、インテントがブロードキャストされmMessageReceiver、in によって受信され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! 

7
ありがとう。すでに動作しています。しかし私が直面した問題は、LocalBroadcastManagerクラスを取得することでした。サポートパッケージクラスなので、Android Toolsから互換性ライブラリを追加するまで、通常のパッケージでは使用できませんでした。追加すると、すべてうまくいきました。とにかく、答えてくれてありがとう
waqaslam 2012年

195
onDestroy()呼び出されることが保証されていないことに注意してください!!! onPause()onPause()が保証されているため)およびonResume()(との一致であるためonPause())を使用する必要があります
18446744073709551615 '26

5
皆さん、GoogleドキュメントでonPause()後のアクティビティについて今言っていることに注意してください。Killable = Pre-HONEYCOMB Honeycombから始めて、アプリケーションはそのonStop()が戻るまでkillable状態になりません。
18446744073709551615

59
onDestroy()問題ありません。呼び出されないのはアプリが強制終了されたときであり、その場合は登録済みのレシーバーのリストでさえ存続しないため、登録を解除しなくてもかまいません。
zapl 2014年

4
@Selvin BroadcastRecieverを受信アクティビティに弱く参照させ、孤立している場合はそれ自体を登録解除させることができることを知っていると思います。BroadcastReceiverを使用してアクティビティをRAMに保持しない限り、onPauseで登録を解除する必要はありません。onDestroyは問題ありません。あなたの例は、内部クラスが外部クラスをリークするという悪い習慣を示しています。これはBroadcastReceiverに固有のものではなく、プログラマーが常に守らなければならないものです。GUIの変更については、アクティビティが再開されたときの状態を保存できるため、GUIを変更する必要はありません。
JohanShogun 2015

133

包括的にお答えしたいと思います。

  1. Android 3.0以降にはLocalbroadcastManagerが含まれているため、初期リリースではサポートライブラリ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 !");
    
        }
    };
  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.
  4. onPauseでの受信機の登録解除:

    protected void onPause() {
      super.onPause();
      LocalBroadcastManager.getInstance(this).unregisterReceiver(onNotice);
    }
  5. アプリケーションのアクティビティまたはサービスからローカルブロードキャストが送信されると、onNoticeのonReceiveが呼び出されます。

編集:ここで完全なチュートリアルを読むことができますLocalBroadcastManager:アプリケーション内メッセージパッシング


15
+1。ブロードキャストレシーバーがフラグメント内にある場合は、それを使用LocalBroadcastManager.getInstance(getActivity()).registerReceiver(onNotice);して登録し、使用して登録を解除しますLocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(onNotice);
PeteH

3
LocalBroadcastManagerがAndroid 3.0以降に含まれていることを確認しますか?サポートlibを除いてどこにもそれを見つけることができません
メンテ

5
奇妙なことに、LBMはサポートライブラリにのみ含まれています。
Jeffrey Blattman、2013

1
super.onPause()は、onPauseメソッドを上書きするときに最後のステートメントにする必要があります。予期しないバグを回避するために、super.onPauseの前に登録を解除する
2016年

2
onStop「マルチウィンドウ/スプリットビュー」を備えたAndroid API 24以降(API 26以降のアフィリエイトではデフォルトで有効になっています)では、インタラクションされていないアクティビティが一時停止状態になっているため、ライフサイクルを移動したいと思うかもしれません。出典:developer.android.com/guide/topics/ui/...
マーティンMarconcini

45

受信側:

  • LocalBroadcastレシーバーの最初の登録
  • 次に、受信インテントデータを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 
              }
          }
      };

送信側:

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

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

私の場合は、ブロードキャストを送信するときに意図的にアクションを設定した場合のみ、それ以外の場合はonReceive()メソッドが呼び出されない...
Akash Bisariya

27

Eclipseでは、プロジェクトを右クリックして以下を選択することにより、最終的に互換性/サポートライブラリを追加する必要がありました。

Android Tools -> Add Support Library

追加さLocalBroadcastManagerれたら、コードでクラスを使用できました。


Android互換ライブラリ


12

グローバルブロードキャストをLocalBroadcastに変更する方法

1)インスタンスを作成する

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);

2)BroadcastReceiverの登録用

交換する

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

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

3)ブロードキャストメッセージの送信用

交換する

sendBroadcast(intent);

localBroadcastManager.sendBroadcast(intent);

4)ブロードキャストメッセージの登録解除用

交換する

unregisterReceiver(mybroadcast);

localBroadcastManager.unregisterReceiver(mybroadcast);

複数のIntentFilterを登録するにはどうすればよいですか?
Parikshit Chalke

@ParikshitChalke:リンク
XMAN

12

localbroadcastmanagerは非推奨です。代わりに、監視可能なパターンの実装を使用してください。

androidx.localbroadcastmanager バージョン 1.1.0 で廃止されます

理由

LocalBroadcastManagerアプリケーション全体のイベントバスであり、アプリのレイヤー違反を受け入れます。どのコンポーネントも他のコンポーネントのイベントをリッスンできます。システムBroadcastManagerの不要なユースケース制限を継承します。オブジェクトは1つのプロセスにのみ存在し、決して離れない場合でも、開発者は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.
        });
    }
}

observe()この方法は、のインスタンスである断片を、通過するLifecycleOwner最初の引数として。そうすることは、このオブザーバーがLifecycle所有者に関連付けられたオブジェクトにバインドされていることを意味します。

  • Lifecycleオブジェクトがアクティブな状態でない場合、値が変更されてもオブザーバーは呼び出されません。

  • Lifecycleオブジェクトが破棄されると、オブザーバーは自動的に削除されます

LiveDataオブジェクトはライフサイクル対応であるため、複数のアクティビティ、フラグメント、サービス間でオブジェクトを共有できます。


1
あなたはコンテキストを全世界にリークすることについて正しいですが、アクティビティがなくても実行されているフォアグラウンドサービスから通信したいのですが、アクティビティが入ったときに通信する必要がある場合、適切な代替品を知りたいのですが?
ateebahmed

1
LiveDataオブジェクトを使用してシングルトンクラスを作成し、サービスからデータを送信します。アクティビティが起動すると、アクティビティは害を及ぼすことなくLiveDataを簡単に監視できます。例:MyServiceData.getInstance()。getMyData()。observe ...
Darish

3
LocalBroadcastManagerを見逃してしまいます。もしそれがグーグルの開発者を混乱させていたなら、多分彼らは過剰にエンジニアリングすることをやめる必要があるのでしょうか?
AFD、

@Darishこのシングルトンクラスは、Applicationオブジェクトに格納することと同等ですか?これらのケースでこの種のグローバルな状態が悪い習慣と見なされないのはなぜですか?
xuiqzy

6

LocalBroadcastReceiverで十分にプレイするときは、Green RobotのEventBusを試してみることをお勧めします。LBRと比較して、その違いと有用性を確実に実感できます。少ないコード、レシーバーのスレッド(UI / Bg)についてカスタマイズ可能、レシーバーの可用性の確認、スティッキーイベント、イベントはデータ配信などに使用できます。


2

LocalBroadcastManagerを実装するアクティビティとサービスの例は、開発者ドキュメントにあります。個人的にはとても便利だと思いました。

編集:それ以降、リンクはサイトから削除されましたが、データは次のとおりです:https : //github.com/carrot-garden/android_maven-android-plugin-samples/blob/master/support4demos/src/com/ example / android / supportv4 / content / LocalServiceBroadcaster.java


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

0

AndroidManifest.xmlファイルでタグ(静的とも呼ばれる)を使用して宣言する

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

上記で宣言されたブロードキャストレシーバーのプロパティは、exported =” true”であることがわかります。この属性は、アプリケーションのスコープ外からブロードキャストを受信できることをレシーバーに伝えます。
2.または、インスタンスをregisterReceiverに登録して動的に(コンテキスト登録と呼ばれるもの)

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

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

ブロードキャストを送信する方法は3つあります
。sendOrderedBroadcastメソッドは、ブロードキャストを一度に1つの受信者にのみ送信するようにします。次に、各ブロードキャストは、データを後続のブロードキャストに渡すか、後続のレシーバーへのブロードキャストの伝播を停止します。
sendBroadcastは、上記の方法と似ていますが、1つだけ違いがあります。すべてのブロードキャストレシーバーはメッセージを受信し、相互に依存しません。
LocalBroadcastManager.sendBroadcastメソッドは、アプリケーション内で定義されたレシーバーにのみブロードキャストを送信し、アプリケーションのスコープを超えません。


-4

broadcastMangerと同じインターフェイスを使用することもできます。ここでは、broadcastManagerのテスト済みコードをインターフェイスで共有しています。

最初に次のようなインターフェイスを作成します。

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

2-これは実装が必要な最初のクラスです

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-メソッドが自動的に呼び出される同じインターフェースを実装する2番目のクラスは次のとおりです。

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

このアプローチにより、broadcastManagerと同じように機能するインターフェースを使用できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.