99

iPhone アプリケーションを Android に移植する過程で、アプリ内で通信するための最良の方法を探しています。インテントが進むべき道のようですが、これが最良の (唯一の) オプションですか? NSUserDefaults は、パフォーマンスとコーディングの両方で Intents よりもはるかに軽量に見えます。

また、状態用のアプリケーション サブクラスがあることも追加する必要がありますが、別のアクティビティにイベントを認識させる必要があります。

4

9 に答える 9

360

私が見つけた最良の同等物は、 Android Support Packageの一部であるLocalBroadcastManagerです。

LocalBroadcastManager のドキュメントから:

プロセス内のローカル オブジェクトにインテントのブロードキャストを登録して送信するためのヘルパー。これには、sendBroadcast(Intent) を使用してグローバル ブロードキャストを送信するよりも多くの利点があります。

  • ブロードキャストしているデータがアプリの外に出ないことはわかっているので、プライベート データの漏洩を心配する必要はありません。
  • 他のアプリケーションがこれらのブロードキャストをアプリに送信することはできないため、悪用できるセキュリティ ホールについて心配する必要はありません。
  • システムを介してグローバル ブロードキャストを送信するよりも効率的です。

Intentこれを使用する場合、 anは an と同等であると言えますNSNotification。次に例を示します。

ReceiverActivity.java

という名前のイベントの通知を監視するアクティビティ"custom-event-name"

@Override
public void onCreate(Bundle savedInstanceState) {

  ...
  
  // Register to receive messages.
  // This is just like [[NSNotificationCenter defaultCenter] addObserver:...]
  // 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.
  // This is somewhat like [[NSNotificationCenter defaultCenter] removeObserver:name:object:] 
  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_sendIntent がブロードキャストされ、 によって受信さmMessageReceiverReceiverActivityます。

デバッグ出力は次のようになります。

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! 
于 2012-01-16T02:42:33.467 に答える
7

これを試すことができます: http://developer.android.com/reference/java/util/Observer.html

于 2011-01-27T17:14:27.017 に答える
4

これを使用できます: http://developer.android.com/reference/android/content/BroadcastReceiver.html、同様の動作を提供します。

Context.registerReceiver(BroadcastReceiver, IntentFilter) を介してプログラムで受信者を登録でき、Context.sendBroadcast(Intent) を介して送信されたインテントをキャプチャします。

ただし、アクティビティ (コンテキスト) が一時停止されている場合、受信者は通知を受け取らないことに注意してください。

于 2011-09-12T13:54:03.630 に答える
0

弱参照を使用できます。

このようにして、メモリを自分で管理し、オブザーバーを好きなように追加および削除できます。

addObserver を追加するときに、これらのパラメーターを追加します。追加するアクティビティからそのコンテキストを空のインターフェイスにキャストし、通知名を追加し、メソッドを呼び出してインターフェイスを実行します。

インターフェイスを実行するメソッドには、次のようなものを渡すデータを返す run という関数があります

public static interface Themethodtorun {
        void run(String notification_name, Object additional_data);
    }

空のインターフェイスで参照を呼び出す監視クラスを作成します。また、addobserver で渡されるコンテキストから Themethodtorun インターフェイスを構築します。

観測をデータ構造に追加します。

それを呼び出すには同じメソッドになりますが、データ構造で特定の通知名を見つけるだけで、Themethodtorun.run(notification_name, data) を使用できます。

これにより、特定の通知名でオブザーバーを作成した場所にコールバックが送信されます。完了したら忘れずに削除してください。

これは弱参照の良い参照です。

http://learningviacode.blogspot.co.nz/2014/02/weak-references-in-java.html

このコードを github にアップロード中です。目を開けてください!

于 2014-09-22T23:03:56.390 に答える
0

LiveDataを使用するiOSと同等の、これと同じ仕事をすることができるラッパーを書きました

ラッパー:

class ObserverNotify {
    private val liveData = MutableLiveData<Nothing>()


    fun postNotification() {
        GlobalScope.launch {
            withContext(Dispatchers.Main) {
                liveData.value = liveData.value
            }
        }
    }

    fun observeForever(observer: () -> Unit) {
        liveData.observeForever { observer() }
    }

    fun observe(owner: LifecycleOwner, observer: () -> Unit) {
        liveData.observe(owner) { observer()}
    }

}

class ObserverNotifyWithData<T> {
    private val liveData = MutableLiveData<T>()


    fun postNotification(data: T) {
        GlobalScope.launch {
            withContext(Dispatchers.Main) {
                liveData.value = data
            }
        }
    }

    fun observeForever(observer: (T) -> Unit) {
        liveData.observeForever { observer(it) }
    }

    fun observe(owner: LifecycleOwner, observer: (T) -> Unit) {
        liveData.observe(owner) { observer(it) }
    }

}

オブザーバー タイプの宣言:

object ObserverCenter {
    val moveMusicToBeTheNextOne: ObserverNotifyWithData<Music> by lazy { ObserverNotifyWithData() }
    val playNextMusic: ObserverNotify by lazy { ObserverNotify() }
    val newFCMTokenDidHandle: ObserverNotifyWithData<String?> by lazy { ObserverNotifyWithData() }
}

観察する活動で:

ObserverCenter.newFCMTokenDidHandle.observe(this) {
    // Do stuff
}

通知するには:

ObserverCenter.playNextMusic.postNotification()
ObserverCenter.newFCMTokenDidHandle.postNotification("MyData")
于 2020-09-23T13:53:06.217 に答える