9

予期しない状況が原因でバインドされたサービスから切断された場合、呼び出した後、onServiceDisconnectedで手動で再接続する必要がありますか、それとも自動的に再接続を試みますか?

public class MyServiceConnection extends Activity implements ServiceConnection {

    MyBinder binder;

    @Override
    protected void onStart() {
        super.onStart();

        connect();
    }

    private void connect() {
        bindService(new Intent(this, MyService.class), 
                this, Service.BIND_AUTO_CREATE);
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        binder = (MyBinder) service;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

        binder = null;

        //should i reconnect here ?
        connect();
    }
}
4

2 に答える 2

15

ServiceConnection APIによると:

public abstract void onServiceDisconnected(ComponentName name)

サービスへの接続が失われたときに呼び出されます。これは通常、サービスをホストしているプロセスがクラッシュまたは強制終了された場合に発生します。これにより、ServiceConnection自体が削除されることはありません。サービスへのこのバインディングはアクティブなままであり、サービスが次に実行されるときにonServiceConnected(ComponentName、IBinder)への呼び出しを受け取ります。

あなたの質問に戻る:

@Override
public void onServiceDisconnected(ComponentName name) {
    binder = null;
    //should i reconnect here ?
    connect();
}

それはすべて、実際のサービスがどのプロセスで実行されるかによって異なります。

ローカルサービス:

サービスは、同じアプリケーションの他のコンポーネント(つまり、それにバインドされたアクティビティ)と同じプロセスで実行されています。この単一のアプリケーションスコープのプロセスがクラッシュまたは強制終了された場合、このプロセスのすべてのコンポーネント(アクティビティを含む)がクラッシュした可能性があります。このサービスにバインドされているもの)も破棄されます。この場合、onServiceDisconnected()内でconnect()を呼び出しても効果はありません。アプリケーションプロセスが回復すると、すべてが最初からロールオーバーされ、アクティビティが再作成され、サービスがアクティビティのonStart()コールバックにバインドされるためです。

リモートサービス:

サービスは別のプロセスで実行されています。このプロセスがクラッシュまたは強制終了されると、実際のサービスのみが破棄され、アクティビティはサービスにバインドされた別のプロセスに残ります。そのため、onServiceDisconnectedでconnect()を呼び出しても問題ありません。 ()サービスを再作成/再バインドするためのコールバック。

AndroidManifest.xmlで別のプロセスで実行されるサービスを構成する方法については、こちらを確認してください。

于 2012-05-24T23:31:35.327 に答える
10

ブログ投稿の調査を行うときに、この古い質問にぶつかりました。受け入れられた答えは非常に良いですが、バインドされたIPC(リモート)サービスに関しては全体像を示していません。

バインドされたIPCサービスへの接続の状態図は次のようになります。

ここに画像の説明を入力してください

そして、OPの質問に対する答えは次のとおりです。それは状況によって異なります。

まず第一に、サービスがクラッシュしたり、OSによって強制終了されたりしても、バインドされたままになります。したがって、問題は、システムがサービスを再作成するかどうかになります...

  • バインドされたIPCサービスがOSによって強制終了された場合、それは再作成され、への呼び出しを受け取るため、onServiceConnected()「再接続」する必要はありません。
  • バインドされたIPCサービスがクラッシュした場合、システムは一度再作成を試みます。2回目にクラッシュした場合、システムは再作成しません(JellyBean、Lollipop、Marshmallowでテスト済み)。

理論的には、次unbindService()bindService()呼び出しのたびに、onServiceDisconnected()これは機能するはずです(私は思います)。

ただし、バインドされたIPCサービス用の本当に信頼できるクライアントを作成するのは少し手間がかかり、一般的なアイデア(チュートリアルアプリと一緒に)はここにあります。

于 2016-06-09T23:30:29.033 に答える