10

標準の Android ドキュメントによると、サービスを開始する (サービスを開始する) ための推奨される方法は、次のような明示的なインテントを使用することです。

// Using explicit intent:
Intent serviceIntent = new Intent(getApplicationContext(), MyService.class);
// or:
Intent serviceIntent = new Intent(this, MyService.class);
startService(serviceIntent);

次のように、マニフェストで指定されたアクション文字列を含む暗黙的なインテントを使用して、サービスを開始/停止することもできます。

// Using implicit intent:
static final String serviceAction = "com.example.my.app.services.MYSERVICE";
Intent serviceIntent = new Intent(serviceAction);
startService(serviceIntent);

// AndroidManifest.xml:
<service android:name="com.example.my.app.services.MyService"
   android:exported="false" android:process=":services" >
   <intent-filter>
      <!-- Start/Stop service -->
      <action android:name="com.example.my.app.services.MYSERVICE" />
   </intent-filter>
</service>

サービスがローカルでのみ使用される場合 (サード パーティ製アプリケーションの開始またはバインドは許可されません)、ドキュメントには、マニフェストサービスタグにインテント フィルターを含めるべきではなく、エクスポートされたタグを false に設定する必要があると記載されています。

注: アクティビティとサービスは別々のプロセス (:application プロセスと :services プロセス) で実行されます。アクティビティとサービスの間の通信は、AIDL インターフェースを実装することによって行われます (これが行われるのは、IPC を同時に処理する必要があるサービス内でマルチスレッドを実行できるのは、AIDL リモート インターフェースだけであるためです。アクティビティ間だけでなく、ほとんどの場合、 内で実行されているサービス間でも同様です。サービスプロセス)。

私の質問は次のとおりです。

Q1: アプリで使用するアクティビティとサービスが 2 つの異なるプロセスで実行される場合、明示的なインテントではなく暗黙的なインテントを使用してサービスを開始および停止する必要がありますか?

Q2: :application プロセスがなくなり (破棄され、メモリ内に存在しなくなり)、:services プロセスがバックグラウンドで実行されている場合、新しい :application プロセスから既に実行中の :services プロセスに再度接続するにはどうすればよいですか? どういうわけか、:services プロセスへの参照を再度取得して、そのプロセス内で実行中のサービスを停止できるようにする必要があります。これは、AIDL afaik を使用して行うことはできません。

問題は、リソースが不足すると、Android が :application プロセスを簡単に破棄できることです。これは、:services プロセスが実行され続ける限り問題ありません。(はい、サービスをフォアグラウンドサービスとして設定するなどしてプロセスに影響を与えることについては知っています。私もマニュアルを読むことができます;)しかし、それは私の問題ではありません)。

アクティビティとサービスが別々のプロセスにあり、AIDL を使用している場合、および :application プロセスが Android によって強制終了された後に :services プロセスを再度「検索」する必要がある場合、またはユーザーがアプリを再度入力します (以前にアプリを離れた後)。

専門家レベルのアドバイスは大歓迎です。

4

2 に答える 2

9

A1 : アクティビティとサービスが異なるプロセスで実行されていても、それらは同じアプリケーションに属しています。明示的な意図を引き続き使用できます。ここで暗黙的な意図を使用することの特定の利点は見られません (見つけたら教えてください:))

A2 : ここにいくつかの事実を挙げさせてください

  • 「開始」サービス (「バインド」サービスではなく) のライフサイクルは、このサービスを開始したアクティビティのライフサイクルとは無関係です。これは、両方が同じプロセスで実行されているかどうかに関係なく当てはまります。
  • どの時点でも、サービスのインスタンスは 1 つだけ有効です。アクティビティが startService() を呼び出すと、まだ実行されていない場合はサービス インスタンスが作成されます (この場合、サービスは onCreate() コールバックも受け取ります)。ただし、サービスが既に実行されている場合、フレームワークは、既に実行中のプロセスで onStartCommand() コールバックを呼び出すだけです (この場合は onCreate() コールバックはありません)。繰り返しになりますが、アクティビティやサービスが同じプロセスまたは異なるプロセスで実行されているかどうかに関係なく、これはすべて当てはまります。

あなたの質問に答えるために、サービスがまだ実行されている場合 (前のアクティビティによる startService() 呼び出しのため)、bindService()/startService() は既存のサービスに確実に接続します。

これがあなたの助けになることを願っています。他に具体的な質問があればお知らせください。

于 2013-11-20T13:11:18.833 に答える