10

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.

4

3 に答える 3

16

サービスに接続するHandlerときにクライアントを登録するサービスで を使用します。ListActivityつまり、 のonServiceConnectedメソッドで、サービスに をListActivity送信しMessageて、接続されたクライアントを追跡できるようにします。次に、これらのクライアントを単純にループして、通知したい何かが発生Serviceしたときに を送信します。詳細については、進行中の私のプロジェクト myおよび my stubのコードを参照してください。MessageServiceListActivityListActivityService

要するに、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);
    }
}
于 2011-07-06T06:20:32.137 に答える
6

すでにサポートライブラリを使用している場合は、LocalBroadcastManagerを使用してサービスからブロードキャストを起動し、送信されているブロードキャストをリッスンするアクティビティに戻すことができます。

LocalBroadcastManagerを使用すると、独自のアプリケーションのみがブロードキャストを受信することが保証されるため、個人データの漏洩や潜在的なセキュリティホールの開放について心配する必要はありません。

LocalBroadcastManagerの使用方法も参照してください。

編集(2014年9月):

これを行うためのより良い方法は、Otto(私のお気に入り)やGreenRobot / EventBusなどのイベントバスフレームワークを使用して、コンポーネントが緊密に結合されすぎないようにすることです。

于 2012-08-09T11:25:02.753 に答える