iPhone アプリケーションを Android に移植する過程で、アプリ内で通信するための最良の方法を探しています。インテントが進むべき道のようですが、これが最良の (唯一の) オプションですか? NSUserDefaults は、パフォーマンスとコーディングの両方で Intents よりもはるかに軽量に見えます。
また、状態用のアプリケーション サブクラスがあることも追加する必要がありますが、別のアクティビティにイベントを認識させる必要があります。
iPhone アプリケーションを Android に移植する過程で、アプリ内で通信するための最良の方法を探しています。インテントが進むべき道のようですが、これが最良の (唯一の) オプションですか? NSUserDefaults は、パフォーマンスとコーディングの両方で Intents よりもはるかに軽量に見えます。
また、状態用のアプリケーション サブクラスがあることも追加する必要がありますが、別のアクティビティにイベントを認識させる必要があります。
私が見つけた最良の同等物は、 Android Support Packageの一部であるLocalBroadcastManagerです。
LocalBroadcastManager のドキュメントから:
プロセス内のローカル オブジェクトにインテントのブロードキャストを登録して送信するためのヘルパー。これには、sendBroadcast(Intent) を使用してグローバル ブロードキャストを送信するよりも多くの利点があります。
- ブロードキャストしているデータがアプリの外に出ないことはわかっているので、プライベート データの漏洩を心配する必要はありません。
- 他のアプリケーションがこれらのブロードキャストをアプリに送信することはできないため、悪用できるセキュリティ ホールについて心配する必要はありません。
- システムを介してグローバル ブロードキャストを送信するよりも効率的です。
Intent
これを使用する場合、 anは an と同等であると言えますNSNotification
。次に例を示します。
という名前のイベントの通知を監視するアクティビティ"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();
}
通知を送信/ブロードキャストする 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
Intent がブロードキャストされ、 によって受信さmMessageReceiver
れ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!
これを使用できます: http://developer.android.com/reference/android/content/BroadcastReceiver.html、同様の動作を提供します。
Context.registerReceiver(BroadcastReceiver, IntentFilter) を介してプログラムで受信者を登録でき、Context.sendBroadcast(Intent) を介して送信されたインテントをキャプチャします。
ただし、アクティビティ (コンテキスト) が一時停止されている場合、受信者は通知を受け取らないことに注意してください。
弱参照を使用できます。
このようにして、メモリを自分で管理し、オブザーバーを好きなように追加および削除できます。
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 にアップロード中です。目を開けてください!
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")