私のアプリには、ユーザー インタラクションのアクティビティと、データ モデルが変更される唯一の場所であるバックグラウンド サービスがあります。バックグラウンド サービスは、ネットワークからの着信メッセージだけでなく、ユーザーが行ったアクションもリッスンします。したがって、並行性の問題が発生する可能性がありますが、ハンドラーを使用して防止しようとしています。イベント レイヤーには、greenrobots Eventbus を使用します。
これはすべてうまく機能していますが、このユースケースを処理するための、よりスマートで高速なコードの広範ではない (したがって、エラーが発生しにくい) 方法があるのだろうか?
もう少し詳しく言うと:
- ハンドラーなしで onEvent メソッドのシリアル実行を保証する方法はありますか?
- 考えられるイベントごとに onEvent メソッドを持つことに代わるものはありますか?
- 私がここでやっていることのより良いパターンはありますか?
これが私のアプローチです:
oncreate メソッドでサービスを登録します(アクティビティの場合は onstart でこれを行います)
@Override
public void onCreate() {
super.onCreate();
...
EventBus.getDefault().register(this);
}
そして onDestroy で、もう一度登録を解除します。
@Override
public void onDestroy() {
super.onDestroy();
....
EventBus.getDefault().unregister(this);
}
着信イベントに反応するときはいつでも、同時実行の問題が発生する可能性があるため、シリアル実行を保証したいと考えています。これは、ユーザー インタラクションやネットワーク経由の他のユーザーからの着信イベントがあるためです。そこで、ハンドラーを使用することにしました。
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
Object receivedEvent = msg.obj;
if(receivedEvent instanceof EditUser)
{
processEditUserBroadcast((EditUser)receivedEvent);
}
else if(receivedEvent instanceof JoinParty)
{
processJoinPartyBroadcast((JoinParty)receivedEvent);
}
else if(receivedEvent instanceof LeaveParty)
{
processLeavePartyBroadcast();
}
else if(receivedEvent instanceof SendMessage)
{
processSendMessageBroadcast((SendMessage)receivedEvent);
}
else if(receivedEvent instanceof ReceivedMessage)
{
processReceivedMessageBroadcast((ReceivedMessage)receivedEvent);
}
else if(receivedEvent instanceof Reset)
{
processResetBroadcast();
}
else if(receivedEvent instanceof ImageDownloadFinished)
{
processImageDownloadFinishedBroadcast((ImageDownloadFinished)receivedEvent);
}
}
};
return handler;
}
関心のあるイベントごとに、小さな「passToHandler」ヘルパー関数を介してシリアル実行を保証するために、イベントをハンドラーに渡すだけの onEvent メソッドがあります。
public void passToHandler(Handler handler, Object object)
{
Message message = handler.obtainMessage();
message.obj = object;
handler.sendMessage(message);
}
public void onEvent(EditUser editUser)
{
passToHandler(handler,editUser);
}
public void onEvent(JoinParty joinParty)
{
passToHandler(handler,joinParty);
}
public void onEvent(LeaveParty leaveParty)
{
passToHandler(handler,leaveParty);
}
public void onEvent(SendMessage sendMessage)
{
passToHandler(handler,sendMessage);
}
public void onEvent(ReceivedMessage receivedMessage)
{
passToHandler(handler,receivedMessage);
}
public void onEvent(Reset reset)
{
passToHandler(handler,reset);
}
public void onEvent(ImageDownloadFinished imageDownloadFinished)
{
passToHandler(handler,imageDownloadFinished);
}
「プロセス..」メソッドは「データマジック」が発生する場所であり、私の質問には関係ありません。
そしてもちろん、可能なイベントごとに、通常は次のように非常にスリムなクラスを作成しました。
public class JoinParty {
private String partyCode;
public JoinParty(String partyCode) {
super();
this.partyCode = partyCode;
}
public String getPartyCode() {
return partyCode;
}
}