I created a service which syncs data from the web on a background thread and want to notify a list activity when the service has completed so it can update it's cursor? What would be the best way to do this? I'm thinking of sending a broadcast when the service is done but not sure if that's the best way to do it. I need to requery the cursor when the service has finished so I'm not sure if that will work well with broadcast receivers? I haven't done alot of android in awhile so thanks in advance.
3 に答える
サービスに接続するHandler
ときにクライアントを登録するサービスで を使用します。ListActivity
つまり、 のonServiceConnected
メソッドで、サービスに をListActivity
送信しMessage
て、接続されたクライアントを追跡できるようにします。次に、これらのクライアントを単純にループして、通知したい何かが発生Service
したときに を送信します。詳細については、進行中の私のプロジェクト myおよび my stubのコードを参照してください。Message
Service
ListActivity
ListActivity
Service
要するに、MainActivity
あなたのサービスを開始してバインドするには、次のようにします。
Intent i = new Intent(this, NetworkService.class);
startService(i);
bindService(i, networkServiceConnection, Context.BIND_AUTO_CREATE);
次のようなサービスからのメッセージに応答するメッセンジャーを定義します。
Messenger messenger = new Messenger(new IncomingHandler());
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case NetworkService.MSG_SOMETHING:
// do something here
break;
default:
super.handleMessage(msg);
}
}
}
次に、サービス接続コードを次のように記述します。
private ServiceConnection networkServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
networkService = new Messenger(service);
try {
Message msg = Message.obtain(null, NetworkService.MSG_REGISTER_CLIENT);
msg.replyTo = messenger;
networkService.send(msg);
log.debug("Connected to service");
} catch (RemoteException e) {
// Here, the service has crashed even before we were able to connect
}
}
replyTo
は作成したばかりのメッセンジャーであることに注意してください。
では、NetworkService
接続されたクライアントを次のように追跡します。
ArrayList<Messenger> clients = new ArrayList<Messenger>();
次のようなハンドラを作成します。
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REGISTER_CLIENT:
log.debug("Adding client: " + msg.replyTo);
clients.add(msg.replyTo);
break;
default:
super.handleMessage(msg);
break;
}
}
}
次に、 にメッセージを送り返したい場合はMainActivity
、次のようにします。
for (int i = 0; i < clients.size(); i++) {
try {
clients.get(i).send(Message.obtain(null, MSG_SOMETHING));
} catch (RemoteException e) {
// If we get here, the client is dead, and we should remove it from the list
log.debug("Removing client: " + clients.get(i));
clients.remove(i);
}
}
すでにサポートライブラリを使用している場合は、LocalBroadcastManagerを使用してサービスからブロードキャストを起動し、送信されているブロードキャストをリッスンするアクティビティに戻すことができます。
LocalBroadcastManagerを使用すると、独自のアプリケーションのみがブロードキャストを受信することが保証されるため、個人データの漏洩や潜在的なセキュリティホールの開放について心配する必要はありません。
LocalBroadcastManagerの使用方法も参照してください。
編集(2014年9月):
これを行うためのより良い方法は、Otto(私のお気に入り)やGreenRobot / EventBusなどのイベントバスフレームワークを使用して、コンポーネントが緊密に結合されすぎないようにすることです。