私のプロジェクトでは、長時間実行中のスレッドからのコールバックとしてBroadcastReceiver
sを使用しています(たとえば、ダウンロードが完了したことをアクティビティに通知し、Worker Thread
から応答データを送信して、アクティビティができるようにしますユーザーに適切なメッセージを表示します。 BroadcastReceiver
sを使用するには、ブロードキャストレシーバーを使用するたびに登録および登録解除するように注意する必要があります。また、このメソッドを使用してさまざまなアクション(ダウンロードなど)を行う場合は、特に送信するメッセージに注意する必要があります。 、WebService呼び出しなどを行います)。また、ブロードキャストの目的でカスタムオブジェクトを送信するには、オブジェクトをParcelable
にする必要もあります。
このアプローチとは異なり、私が使用するメソッドよりも単純に見えるコールバックメソッドのアプローチも見ました。コールバックメソッドは、アプリメッセージングのBroadcastRecaiverと同じ効果を達成するために使用できるシンプルなインターフェイスメソッドの実装です。このアプローチは、複雑なオブジェクトを返すためにParcelable実装を必要とせず、BroadcastReceiver
のようなキーを使用しません。悪い点は、コールする前にコールバックオブジェクトのnull値を確認する必要があることですコールバックメソッドと、UIスレッドの実装からコードを実行していることを確認して、エラーなしでUIを更新できるようにします。
わかりました、私が言うつもりのことを理解していただければ幸いです:)。
質問は、単一のアプリケーションの内部でのみ使用する場合、コールバックメソッドはBroadcastReceiver
アプローチよりも優れている(軽量、クリーン、高速)と思いますか? (私はAndroid Service
をバックグラウンドで使用していないことに注意してください。AsyncTask
とThread
sのみ)
ありがとうございました!
これは非常に興味深い質問で、同じ問題に遭遇しました。私の意見では、両方のメカニズムを完全に使用することができ、使用する適切なアプローチはユースケースに依存します。決定する前に考慮すべきいくつかのポイントがあります。
コールバックメカニズムの使用にはいくつかの利点がありますが、制限もあります。
プロ
コントラ
Observer
/Observable
メカニズムを使用します。null
を確認する必要があります。BroadcastReceiver
-アプローチに関するいくつかのポイント:
プロ
onReceive()
メソッドは常にメインスレッドで実行されます。コントラ
Intent
によって転送されるデータのマーシャリングとアンマーシャリングは追加のエラーソースです。Intent
のアクションを一意にする必要があります(パッケージ名の先頭に追加するなど)。その本来の目的は、アプリケーション間のブロードキャストを行うことです。BroadcastReceiver
- registrationおよびunregistrationを管理する必要があります。これをより快適な方法で行いたい場合は、登録する必要のあるアクションでアクティビティに注釈を付けるカスタムアノテーションを実装し、onResume()
でActivity
sの登録と登録解除を行うベースIntentFilter
classを実装できます。それぞれ。 onPause()
methods。Intent
で送信されるデータはParcelable
インターフェースを実装する必要がありますが、さらに厳密なサイズ制限があり、Intent
で大量のデータを転送するとパフォーマンスの問題が発生します。これについての議論は http://code.google.com/p/Android/issues/detail?id=5878 を参照してください。したがって、たとえば画像を送信する場合は、一時的にリポジトリに保存し、対応するIDまたはURLを送信して、使用後にリポジトリから画像を削除するIntent
のレシーバーから画像にアクセスする必要があります。複数のレシーバーがある場合、これによりさらに問題が発生します(いつイメージをリポジトリーから削除する必要があり、誰が削除する必要がありますか?)。Intent
sのシーケンスでグラフを描画することになり、特定のエラーの原因となった原因や、この通知チェーンがどこかで壊れた理由がわかります。私の意見では、モバイルアプリでも、少なくとも2つのレイヤー(UIレイヤーとコアレイヤー(ビジネスロジックなどを含む))に基づくアーキテクチャが必要です。一般に、長時間実行タスクはコアレイヤー内の独自のスレッドで(おそらくAsyncTask
またはHandlerThread
を使用する場合はMessageQueue
を介して)実行され、このタスクが完了したらUIを更新する必要があります。一般に、コールバックを使用すると、コンポーネント間の密結合が実現されるため、このアプローチはレイヤー内でのみ使用し、レイヤーの境界を越えた通信には使用しないことをお勧めします。 UIレイヤーとコアレイヤーの間のメッセージブロードキャストでは、ロジックレイヤーからUIレイヤーを分離できるBroadcastReceiver
-アプローチを使用します。
あなたの場合、BroadcastReceiver
を使って何が得られるかわかりません。コールバック、またはおそらくHandlers
がその方法です。 BroadcastReceiver
は、サブスクライバーが誰かわからない場合に適しています。
私はあなたがすでに受け取った他の素晴らしい答えに別のオプションを追加します...
インテントを受信するためにブロードキャストレシーバーを作成する必要はありません。 Androidマニフェストファイルに、インテントを受信するためのアクティビティを登録できます。
_<activity Android:name=".MyActivity">
<intent-filter >
<action Android:name="intent.you.want.to.receive" />
<category Android:name="Android.intent.category.DEFAULT" />
</intent-filter>
....
</activity>
_
次に、アクティビティのonNewIntent(Intent)
メソッドをオーバーライドして受け取ります。
インテントを送信するには、Context.startActivity(Intent)
メソッドを使用します。おそらく、_FLAG_ACTIVITY_SINGLE_TOP
_フラグをインテントに追加して、アクティビティのインスタンスが既に実行されている場合に、アクティビティの新しいインスタンスが作成されないようにする必要があります。
編集:私はあなたが単一のアプリケーション内で実行されていることに気づきました。したがって、単純なコールバックがおそらく最善です。上記のソリューションは単一のアプリで機能しますが、さまざまなアプリケーションに適しています。これは誰かを助けるためにここに置いておきます。幸運を!
Broadcastreceiversを使用する必要があるのは、アプリケーション間でブロードキャストを送信する必要がある場合です。
これら2つ以外を使用する場合は、 Observer (インターフェースはAndroidに含まれています)とデリゲートの使用を検討してください。
デリゲートについては this SO post を検討してください。
目標は不明ですが、intentとbroadcastReceiverを使用するという同じ考えを維持し、通常のbroadcastReceiversよりも優れたパフォーマンスとセキュリティが必要な場合は、Androidサポートで利用できるこのデモを試すことができます図書館 :
そうでない場合は、常にasyncTask、service、handlersなどを使用できます。