START_STICKY,前台 Android 服务消失,恕不另行通知
我已经在我的新应用程序中启动了一项服务。该服务位于前台,并带有通知。当它在 AVD 2.1 API Level 7 中运行时,一切正常。但是,当它在运行 Gingerbread 的三星 Galaxy Tab 上运行时,该服务将启动(图标和应用程序名称出现在通知区域的顶部),但几秒钟后,该服务就会消失。我可以看到的日志中的最后一个条目与我的应用程序相关联,是我的 Log.d("Taglines","Returning with " + START_STICKY) 的结果,它紧接在 "return START_STICKY ;" 之前在我的服务的 onStartCommand 覆盖中,如下所示:
@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 ;
}
通知设置如下:
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");
}
这是服务启动时“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: 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
我认为在这种情况下不需要它,但这是 AndroidManifest.xml 的相关部分:
<service android:name=".TagsManager"
android:exported="false">
</service>
我可能在哪里出错了?我还可以提供哪些其他信息?
I have started a service in my new application. The service is foregrounded, with a Notification. When this is run in the AVD 2.1 API Level 7, all works fine. But when it's run on a Samsung Galaxy Tab running Gingerbread, the service will start (the icon and app name appear at the top of the notification area), but after a few seconds, the service disappears. The last entry in the Log that I can see is associated with my App, is the result of my Log.d("Taglines","Returning with " + START_STICKY), which immediately precedes "return START_STICKY ;" in my Service's onStartCommand override, as follows:
@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 ;
}
The notification is set like this:
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");
}
This is the result from "adb logcat" when the service is started:
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
After that, nothing special (nothing at all from PID 21863). Just a bunch of:
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
I don't think it's needed in this case, but here's the relevant portion of the AndroidManifest.xml:
<service android:name=".TagsManager"
android:exported="false">
</service>
Where might I have gone wrong? What other information can I provide?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有几件事:
摆脱
mNotificationManager.notify(NOTIFICATION_ID, notification);
。startForeground()
为您显示通知图标。前台
Service
仍然可以被杀死,只是可能性较小。2.3 中有一个错误(不确定是否已修复),当
Service
被终止并重新启动时,其onStartCommand()
将不会再次调用。相反,您必须在onCreate()
中进行任何设置。A few things:
Get rid of the
mNotificationManager.notify(NOTIFICATION_ID, notification);
.startForeground()
displays the notification icon for you.Foreground
Service
s can still be killed, they're just less likely to be.There's a bug in 2.3 (not sure if it was fixed yet) where when a
Service
is killed and restarted, itsonStartCommand()
will NOT be called again. Instead you're going to have to do any setting up inonCreate()
.这两段代码仅在手机内存不足并在完成执行之前终止
Service
时相关。START_STICKY
告诉操作系统在拥有足够内存后重新创建服务,并以空意图再次调用onStartCommand()
。START_NOT_STICKY
告诉操作系统不必再次重新创建服务。还有第三个代码START_REDELIVER_INTENT
告诉操作系统重新创建Service
并将相同的意图重新传递给onStartCommand()
。本文,作者:Dianne Hackborn比官方文档更好地解释了这个背景。
这里的关键部分是函数返回的新结果代码,告诉系统如果服务进程在运行时被终止,应该如何处理该服务:
Both codes are only relevant when the phone runs out of memory and kills the
Service
before it finishes executing.START_STICKY
tells the OS to recreate the service after it has enough memory and callonStartCommand()
again with a null intent.START_NOT_STICKY
tells the OS to not bother recreating the service again. There is also a third codeSTART_REDELIVER_INTENT
that tells the OS to recreate theService
AND redelivery the same intent toonStartCommand()
.This article by Dianne Hackborn explained the background of this a lot better then the official documentation.
The key part here is a new result code returned by the function, telling the system what it should do with the service if its process is killed while it is running: