START_STICKY, Vorder-Android-service geht Weg ohne es zu bemerken
Habe ich begonnen, einen Dienst in meiner neuen Anwendung. Der service im Vordergrund, mit einer Benachrichtigung. Wenn diese ausgeführt wird, in der AVD 2.1-API Level 7, alles funktioniert einwandfrei. Aber wenn es laufen auf einem Samsung Galaxy Tab mit dem Betriebssystem Gingerbread, der Dienst wird gestartet (das icon und app-name erscheint oben in der notification-area), aber nach ein paar Sekunden, der service verschwindet. Der Letzte Eintrag im Log, dass ich sehen kann, ist verbunden mit my App, ist das Ergebnis meiner Log.d("Taglines","die Rückkehr mit" + START_STICKY), die unmittelbar vor "return START_STICKY ;" in meinem Dienst ist onStartCommand überschreiben, wie folgt:
@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 ;
}
Die Benachrichtigung festgelegt ist, wie diese:
void createNotification(String text) {
Log.d("Taglines","createNotification called");
if (mNotificationManager == null) {
//Get a reference to the Notification Manager
String ns = Context.NOTIFICATION_SERVICE;
mNotificationManager = (NotificationManager) getSystemService(ns);
Log.d("Taglines","Obtained reference to Notification Manager");
}
//Instantiate the Notification
int icon = R.drawable.ic_notification;
CharSequence tickerText = "Taglines";
long when = System.currentTimeMillis();
notification = new Notification(icon, tickerText, when);
//Define Notification's expanded message and intent
Log.d("Taglines","createNotificacion() .. getApplicationContext");
context = getApplicationContext();
contentText = text;
//notificationIntent = new Intent(this, TagsOverview.class);
notificationIntent = new Intent(this, TagsServiceMenu.class);
contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
//Pass the Notification to the NotificationManager:
Log.d("Taglines","createNotificacion() ... passing notification");
mNotificationManager.notify(NOTIFICATION_ID, notification);
Log.d("Taglines","Starting foreground");
startForeground(NOTIFICATION_ID, notification);
Log.d("Taglines","Started");
}
Dies ist das Ergebnis von "adb logcat", wenn der Dienst gestartet wird:
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
Danach, nichts besonderes (gar nichts von PID-21863). Nur ein Haufen von:
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: com.android.internal.view.IInputMethodClient$Stub$Proxy@40bc06e8
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
Ich glaube nicht, dass es in diesem Fall benötigt, aber hier ist der relevante Teil der AndroidManifest.xml:
<service android:name=".TagsManager"
android:exported="false">
</service>
Wo könnte ich falsch gegangen? Welche weiteren Informationen kann ich bieten?
- Hmmm... ich lese mehr über startForeground, und es scheint, dass diese gerade legt ein flag auf ein notification-Objekt, anstatt wirklich etwas action. So, aus einer Laune heraus, habe ich die umgekehrte Reihenfolge, so dass nun startForeground vor NotificationManager.Benachrichtigen Sie. Bisher schaut es ganz gut aus. So, jetzt bin ich auf der Suche nach diesem Beispiel, das führte mich, es zu tun die andere Weise...
- Leider, der Erfolg der Umkehrung dieser Sequenz war von kurzer Dauer. Scheint ein bisschen wie ein Glücksspiel, ob der sticky "klebt." Mit vielen Dutzenden versuchen auf diesen Dienst starten, habe ich es bleiben, begann drei mal so weit. 🙁
- Naja, war Ihr Galaxy Tab erleben low-memory Bedingungen, oder vielleicht Ihr Service war etwas zu tun Arbeitsspeicher intensiv auf den Haupt-thread?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ein paar Dinge:
Loszuwerden, die
mNotificationManager.notify(NOTIFICATION_ID, notification);
.startForeground()
zeigt das Benachrichtigungs-Symbol für Sie.Vordergrund
Service
s können immer noch getötet werden, Sie sind nur weniger wahrscheinlich zu sein.Da ist ein Fehler in 2.3 (nicht sicher, wenn es noch nicht fest), wo, wenn ein
Service
getötet wird und neu gestartet wird, seineonStartCommand()
wird NICHT erneut aufgerufen werden. Anstatt Sie gehen zu müssen, um jede Einrichtung inonCreate()
.Beide codes sind nur relevant, wenn das Telefon läuft out of memory und tötet die
Service
bevor es abgeschlossen ist.START_STICKY
sagt das OS neu service nach, es hat genug Speicher und rufenonStartCommand()
wieder mit einem null-Absicht.START_NOT_STICKY
sagt das OS nicht die Mühe der Neuerstellung der service wieder. Es gibt auch noch einen Dritten codeSTART_REDELIVER_INTENT
sagt das OS neu zu erstellenService
- UND Rücklieferung der gleichen Absicht zuonStartCommand()
.Dieser Artikel von Dianne Hackborn erklärt den hintergrund dieses um einiges besser als die offizielle Dokumentation.
Den wichtigsten Teil hier ist ein neues Ergebnis-code von der Funktion zurückgegeben wird, sagt das system, was sollte er mit dem service zu tun, wenn sein Prozess wird getötet, während er ausgeführt wird: