2013-03-16 43 views
31

センサーデータを収集するバックグラウンドサービスが作成されているアプリケーションを開発しています。アプリケーションが終了すると、Androidバックグラウンドサービスが再起動しています

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

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

UPDATE:

以下の回答で示唆したように、私はサービスで、以下の方法が、運を追加しました。

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

これは私にも起こります。そして、私はバインドもしていません – fersarr

+1

あなたはそれを言及していません:あなたはAndroidManifestでサービスのための別のグローバルプロセスを指定しようとしましたか? – Stevie

+0

解決方法はありますか? –

答えて

0

あなたがIntentServiceを使用している場合、それはあなたが実行する必要のあるコードを配置する必要があり

​​

方法があります。別のスレッド(アプリケーションが実行されているUIスレッドではありません)で実行されるため、アプリは影響を受けません。コードの実行が終了すると、スレッドは終了し、サービスは自動的に停止します。

+3

私は彼がIntentService(onHandleINtentメソッドを持っている)を参照するのではなく、単純なもの(Service)を参照していると思います。 – fedepaol

+0

彼は指定しなかったが、おそらくあなたは正しい。 –

+0

申し訳ありませんが、私は初心者です。はい、私は '普通のサービス'を指しています – user1135357

17

これは、onStartCommandで返される値によって異なります。あなたはdocumentationによるSTART_NOT_STICKY

を返さなければなりません

始めたサービスでは、彼らが実行することを決定することができる操作の二つの追加のメジャーモードでは、彼らはonStartCommandから返す値に応じて、そこにあります():START_STICKYは、START_NOT_STICKYまたはSTART_REDELIVER_INTENTが、送信されたコマンドの処理中に実行されているだけのサービスに対して使用されているときに、明示的に開始および停止されたサービスに使用されます。

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

このすべてが私の好奇心を引き起したので、私はこれをテストするためのサンプルアプリケーションを作成しました。すべてのジップを見つけることができますsources here startServiceボタンとstopServiceボタンがあります。 サービスはonStartCommandでSTART_NOT_STICKYを返します。 私はトーストをonCreate、onStartCommand、onDestroyに配置しました。

何が起こるかをここで

  • 私はスタートを押すと、のonCreateとONSTARTが
  • と呼ばれている私は停止を押すと、onDestroyが
  • をトリガされ、私は二回起動押すと、のonCreateが一度onStartCommandと呼ばれています2回

これは期待通りに動作します。

説明したようにサービスを開始してアプリケーションを終了すると、onDestroyは呼び出されず、onCreateまたはonStartのどちらも呼び出されません。

私がアプリに戻ってスタートをもう一度押すと、onCreateはと呼ばれます。これは前に書いたように、サービスが自動的に再開するのを防ぎます。

サービスにもう一度サービスを開始するアプリがあると思います(保留中の予定)。

+0

私はすでにそれを試みましたが、問題は持続しました。 – user1135357

+1

アプリケーションを "どのように"殺すのですか?そして、あなたはonCreate()とonStart()が何度も繰り返し呼び出されていることをどのように知っていますか? – fedepaol

+2

最近のAppsトレイ(Android 4.1.1で動作しているGalaxy Nexusがあります)でアプリをスワイプしてアプリケーションを終了します。私は、2つのメソッドの開始時にトースト通知を表示するので、onCreate()とonStart()が再び呼び出されることを知っています – user1135357

-2

メモリが不足すると、バックグラウンドで実行されているサービスが自動的に終了します。 startService()を使用してサービスを開始する代わりに、StartForeground()を代わりに使用してみてください。サービスはフォアグラウンドで実行され、メモリが少なくても決して殺されません。

+0

あなたは(正しく)質問を読んでいない。 – Boy

+0

「絶対に殺されない」ということについて厳密には真実ではありませんが、極端な場合でも殺される可能性は低いですが、 – EnduroDave

-2

同じ問題が発生し、サービスをグローバルプロセスで実行することで解決できました。

私はこれをしたときに私が見つけた

プロセス=「com.myapp.ProcessName」

(任意の名前を構成してください。):あなたはマニフェストタグに以下を追加することで、これを行いますアプリがリストからスワイプされると、私のサービスは殺されなかった(そして再開された)。おそらくこれは、あなたがそれをスワイプしたときにアプリプロセスが殺されるが、グローバルサービスプロセスは殺されないからである。

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

+0

これは私のためには機能しません。少なくともAndroidではない5.1.1 –

+0

動作しません。 – Abbath

4

アプリとサービスは同じプロセスで生きています。つまり、アプリが殺されたときにあなたのサービスが殺されたことを意味します。 onStartCommandの戻り値を変更しても、このプロセスには影響しません。それは、あなたがそれを言うとき、またはそれが必要なことをやり終えたときに、サービスに開始/停止のいずれかを単に伝えるだけです。あなたの元の投稿へのあなたのコメントで述べたように、フォアグラウンドプロセスとして設定することはできましたが、それは本当にサービスに高い優先度を与えて、問題を解決することではありません。

サービスを別々に殺すように変更し、onStartCommandを使用するためにバインドされたサービスではなく開始済みのサービスであると仮定して、そのサービスのマニフェストにプロセス名を指定します。 Process and Threads Developer Guideから

<activity>, <service>, <receiver>, and <provider>、エレメント成分の種類ごとにマニフェストエントリ - は、Androidをサポート:プロセス属性そのコンポーネントが実行するべき プロセスを指定することができます。 この 属性は、各コンポーネントが独自のプロセスで実行されるように設定することができます。 一部のコンポーネントはプロセスを共有しますが、他のコンポーネントはプロセスを共有しません。また、異なるアプリケーションの コンポーネントが同じ プロセスで実行されるように、android:processを設定して、アプリケーションが同じ LinuxユーザーIDを共有し、同じ証明書で署名されるようにすることもできます。

メモリが不足しており、他のユーザーがすぐに処理しているプロセスによって、Androidがプロセスをシャットダウンすることがあります( )。 プロセスで実行されているアプリケーションコンポーネントが であり、結果として破壊されます。プロセスが再び開始されると、それらのコンポーネントのプロセスが再び開始されます。 <service> in Manifest Fileから

アンドロイド:プロセス

サービスを実行しているプロセスの名前。 通常、アプリケーションのすべてのコンポーネントは、アプリケーション用に作成されたデフォルトプロセス で実行されます。これはアプリケーション パッケージと同じ名前です。要素のprocess属性では、すべてのコンポーネントに対して異なるデフォルト値を に設定できます。しかし、コンポーネントは のデフォルトを独自のプロセス属性で上書きできるため、 アプリケーションを複数のプロセスに分散することができます。

この 属性に割り当てられた名前は、コロン(「:」)で始まる場合、 アプリケーションにプライベート新しいプロセスは、それが必要だときに作成およびサービスは、その プロセスで実行されています。プロセス名が小文字で始まる場合、 サービスはその名前のグローバルプロセスで実行されます(但し、 にはそのような権限があります)。これにより、異なるアプリケーション内のコンポーネントがプロセスを共有し、リソースの使用を減らすことができます。

これについて言及した他の回答が投票に失敗した理由がわかりません。私は過去にこのメソッドを使用していましたが、今日は、私が狂っていないことを確認するために、異なるプロセスでサービスを持つシンプルなアクティビティアプリケーションを作成しました。 Androidのデバイスモニタを使用してアプリのプロセスを終了しました。 ADMの両方のプロセスを分けて見ることができ、アプリケーションのプロセスが強制終了されると、サービスが停止していることがわかります。

0

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

破壊することができたりなど、音楽のようなユーザーエクスペリエンスに影響を与えることができ、サービスがある場合、あなたは通知を使用する必要があり、サービスが正常に開始されたとき、その関数を通知を作成し、使用している場合は

startForeground(int Notification_id,Notification); 

これは、再起動することなく、バックグラウンドであなたのサービスを実行し、その方法

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

0

スタートキットカットの上に作業し、他のonTaskRしない粘着性のないを再呼び出ししますマシュマロの上で働かなかった。 onTaskRemovedは、いくつかの例外を処理することによって使用できます。それに取り組まなかった。しかし、それを試してみてください。

関連する問題