2011-07-08 8 views
7

新しいアプリケーションでサービスを開始しました。サービスは通知付きでフォアグラウンドになっています。これをAVD 2.1 APIレベル7で実行すると、すべて正常に動作します。しかし、Gingerbreadを実行しているSamsung Galaxy Tabで実行すると、サービスが開始されます(通知エリアの上部にアイコンとアプリ名が表示されます)が、数秒後にサービスが消えます。私が見ることができるログの最後のエントリは、自分のアプリケーションに関連付けられています。私のLog.d( "タグライン"、 "START_STICKYを返す" + START_STICKY)の結果です。私のサービスのonStartCommandオーバーライドでは、次のように:START_STICKY、フォアグラウンドのAndroidサービスが予告なしに終了する

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

    int rc ; 
    Log.d("Taglines","onStartCommand()"); 
    Toast.makeText(this, "Starting service TagsManager", Toast.LENGTH_SHORT).show(); 
    Log.d("Taglines","Calling super.onStartCommand()"); 
    rc = super.onStartCommand(intent,flags,startId); 
    Log.d("Taglines","super.onStartCommand return code was " + rc); 
    createNotification(INITIAL_NOTIFICATION_TEXT); 
    Log.d("Taglines","Returning with " + START_STICKY); 
    return START_STICKY ; 
} 

通知は、次のように設定されている:サービスが開始されたときに

これは、 "ADB logcat" からの結果である:

D/Taglines(21863): Starting service 
D/Taglines(21863): TagsManager(nullary) completed 
D/Taglines(21863): onStartCommand() 
D/Taglines(21863): Calling super.onStartCommand() 
D/Taglines(21863): super.onStartCommand eturn code was 2 
D/Taglines(21863): createNotification called 
D/Taglines(21863): Obtained reference to Notification Manager 
D/Taglines(21863): createNotificacion() .. getApplicationContext 
D/Taglines(21863): createNotificacion() ... passing notification 
D/Taglines(21863): Starting foreground 
D/Taglines(21863): Started 
D/Taglines(21863): Returning with 1 

その後、特別なことは何もありません(PID 21863から何もありません)。ちょうど束:

D/KeyguardViewMediator( 302): setHidden false 
D/KeyguardViewMediator( 302): setHidden false 
D/KeyguardViewMediator( 302): setHidden false 
D/KeyguardViewMediator( 302): setHidden false 
D/KeyguardViewMediator( 302): setHidden false 
W/InputManagerService( 302): Window already focused, ignoring focus gain of:   [email protected] 
D/KeyguardViewMediator( 302): setHidden false 
D/KeyguardViewMediator( 302): setHidden false 
D/KeyguardViewMediator( 302): setHidden false 
D/KeyguardViewMediator( 302): setHidden false 
D/KeyguardViewMediator( 302): setHidden false 
D/KeyguardViewMediator( 302): setHidden false 
D/KeyguardViewMediator( 302): setHidden false 
D/KeyguardViewMediator( 302): setHidden false 
D/KeyguardViewMediator( 302): setHidden false 

私はそれが、この場合に必要だとは思わないが、ここでのAndroidManifest.xmlの関連部分だ:私が間違っている場合があります

<service android:name=".TagsManager" 
      android:exported="false"> 
    </service> 

は?他にどんな情報を提供できますか?

+0

Hmmm ...私はstartForegroundについてもっと読んでいます。実際に何らかのアクションを取るのではなく、通知オブジェクトにフラグを設定するようです。ですから、私はシーケンスを逆にしてstartForegroundがNotificationManager.notifyに先行するようにしました。これまでのところ、それはかなり良く見えています。だから今私はそれを他の方法でやってくれたその例を探しています... – Dennis

+0

悲しいことに、そのシーケンスを逆転させることの成功は短命でした。スティッキーが「固執する」かどうかについての賭けのビットであるように思えます。 _many_何十ものこのサービスを開始しようと試みて、私はそれまで3回始まっています。 : – Dennis

+0

まあ、あなたのギャラクシータブはメモリ不足の状態でしたか、おそらくあなたのサービスはメインスレッドで何かメモリ集中をしていましたか? –

答えて

10

いくつかのこと:

  1. mNotificationManager.notify(NOTIFICATION_ID, notification);を取り除きます。 startForeground()に通知アイコンが表示されます。

  2. Foreground Serviceはまだ殺される可能性があります。

  3. Serviceが殺され、再起動されたときに、そのonStartCommand()が再び呼び出されません(それはまだ修正されたかどうかわからない)2.3のバグがあります。代わりに、onCreate()に設定を行う必要があります。

+0

ありがとう、これはすべて意味があります。 – Dennis

+0

+1ありがとうございました。2.3のバグ、iOSのバグ... OSにバグがどこにあってもクライアントのためのソフトウェアを書く方法:) - yah、プラットフォームに依存しないフレームワークで! :)私はSTART_STICKYを使用して、時にはonDestroy()が再作成されます... –

1

両方のコードは、電話機がメモリ不足になったときにのみ有効で、実行が完了する前にServiceを終了します。 START_STICKYは、十分なメモリがある場合にOSにサービスを再作成し、ヌルインテントでonStartCommand()を再度呼び出すように指示します。 START_NOT_STICKYは、OSにサービスの再作成を邪魔しないように指示します。 OSにService再配信と同じ意図をonStartCommand()に再作成するように指示する第3コードSTART_REDELIVER_INTENTもあります。

This article Dianne Hackbornさんが、この背景を説明してくれました。そのプロセスが殺されている場合、それが実行されている間

ここで重要な部分は、それがサービスと何をすべきかのシステムを伝える、関数によって返された新しい結果コードです:

START_STICKYは基本的に同じです前の動作では、 サービスは「開始済み」のままで、後でシステムによって再起動されます。 プラットフォームの以前のバージョンとの唯一の相違点は、プロセスが強制終了されたために再起動された場合、 は、サービスの次のインスタンスに対してonStartCommand() が呼び出されず、nullインテント 。このモードを使用するサービスは、常に がこのケースをチェックし、適切に対処する必要があります。

START_NOT_STICKYはonStartCreated()から戻った後に残っスタートが提供するコマンドないと、 場合、プロセスが殺され、 は、サービスが停止の代わりに、再起動される、と述べています。これにより、 コマンドを実行している間だけ実行されるサービスに対して、 の方がより意味を持ちます。たとえば、アラームから何らかのネットワーク状態をポーリングするために、15分ごとにサービスを開始することがあります( )。その作業中に が殺された場合は、次回にアラームが発生したときには を停止して開始するのが最善です。 サービスのプロセスが殺されている場合を除いて、それが完了するまで、それはそれに再配信されます与えられた 意図、その意図についてstopSelf()を呼び出す前に

START_REDELIVER_INTENTは、START_NOT_STICKYのようなものです (ない限り、より多くの試行のいくつかの番号の後にそれでも、完了することはできません、 の時点で、システムはあきらめます)。これは、作業のコマンドを受け取っている であり、最終的に が送信された各コマンドの作業を完了することを確認したいサービスに役立ちます。

関連する問題