38

センサー データを収集するバックグラウンド サービスを作成するアプリケーションを開発しています。私は自分のアクティビティからサービスを開始しています:

startService(new Intent(this, MyService.class));

このサービスを作成したので、アプリケーションが破棄されても、バックグラウンド サービスは引き続きデータを収集します。これを試してみたところ、ある程度はうまくいきました。私の問題は、アプリケーションを強制終了すると、onCreate()サービスとonStart()メソッドが呼び出されるため、サービスが再起動するように見えることです。サービスを再起動しない方法はありますか?

アップデート:

以下の回答で示唆されているように、サービスに次のメソッドを追加しましたが、うまくいきませんでした。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_NOT_STICKY;
}
4

6 に答える 6

20

onStartCommandで返される値によって異なります。

START_NOT_STICKYを返す必要があります

ドキュメントによると:

開始されたサービスの場合、onStartCommand()から返される値に応じて、実行を決定できる2つの主要な操作モードがあります。START_STICKYは、必要に応じて明示的に開始および停止されるサービスに使用され、START_NOT_STICKYまたはSTART_REDELIVER_INTENTが使用されます。送信されたコマンドの処理中にのみ実行を継続する必要があるサービスの場合

つまり、START_STICKYを返すと、リソースが利用可能になるたびにサービスが再作成されます。START_NOT_STICKYを返す場合は、新しいインテントを送信するサービスを再度アクティブ化する必要があります。

これらすべてが私の好奇心を刺激したので、これをテストするためのサンプルアプリを作成しました。ここにすべてのソースを含むzip があります。startServiceボタンとstopServiceボタンがあり、それらに期待することを実行します。サービスはonStartCommandでSTART_NOT_STICKYを返します。onCreate、onStartCommand、onDestroyにトーストを配置しました。

ここで何が起こりますか:

  • スタートを押すと、onCreateとonStartが呼び出されます
  • 停止を押すと、onDestroyがトリガーされます
  • スタートを2回押すと、onCreateが1回呼び出され、onStartCommandが2回呼び出されます。

したがって、期待どおりに動作します。

説明したようにサービスを開始してアプリを強制終了すると、onDestroyは呼び出されませんが、onCreateもonStartも呼び出されません。

アプリに戻ってもう一度[開始]を押すと、onCreateが呼び出されます。これは、前に書いたように、START_NOT_STICKYによってサービスが自動的に再起動されないことを意味します。

アプリにサービスを再開する何かが他にあると思います(おそらく保留中のインテント)。

于 2013-03-16T18:28:10.137 に答える
0

この質問に答えるのがかなり遅れていることはわかっていますが、他の人にとっては役立つかもしれません. これは、私の音楽プレーヤーアプリにとって本当に役に立ちました。

音楽などのユーザー エクスペリエンスを混乱させたり、影響を与えたりする可能性のあるサービスがある場合、その場合は通知を使用する必要があり、サービスが正常に開始されたら、通知を作成して関数を使用します。

startForeground(int Notification_id,Notification);

これにより、メソッドを再起動して再度呼び出すことなく、サービスがバックグラウンドで実行されます

https://developer.android.com/reference/android/app/Service.html

于 2016-09-28T16:27:22.383 に答える
0

IntentService を使用している場合は、

onHandleIntent() 

実行する必要があるコードを配置するメソッド。これは別のスレッド (アプリケーションが実行される UI スレッドではない) で実行されるため、アプリはそれに影響を与えるべきではありません。コードの実行が終了すると、スレッドが終了し、サービスが自動的に停止します。

于 2013-03-16T18:27:20.710 に答える
0

私は同じ問題に遭遇し、サービスをグローバル プロセスで実行することで解決できました。これを行うには、マニフェスト タグに次を追加します。

process="com.myapp.ProcessName"

(どんな名前でも構いません。)

これを行ったとき、アプリがリストからスワイプされたときに、サービスが強制終了 (および再起動) されていないことがわかりました。これはおそらく、スワイプするとアプリ プロセスが強制終了されるためですが、グローバル サービス プロセスは強制終了されないためです。

これの欠点は、アプリとサービス間の通信が IBinder インターフェイス経由で行われる必要があることです。アプリケーションまたはサービスの関数を他の関数から直接呼び出すことはできません。これらは異なるプロセスで実行されているためです。

于 2015-04-01T15:50:54.810 に答える