START_STICKY,前台Android服务在没有通知的情况下消失

我已经在我的新应用程序中启动了一项服务。 该服务是预先通知,通知。 当它在AVD 2.1 API Level 7中运行时,一切正常。 但是当它在运行姜饼的三星Galaxy Tab上运行时,服务将开始(图标和应用程序名称出现在通知区域的顶部),但几秒钟后,服务消失。 我可以看到的日志中的最后一个条目与我的应用程序相关,是我的Log.d(“标语符号”,“+ 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> 

我可能在哪里出错了? 我还能提供哪些其他信息?

Solutions Collecting From Web of "START_STICKY,前台Android服务在没有通知的情况下消失"

一些东西:

  1. 摆脱mNotificationManager.notify(NOTIFICATION_ID, notification);startForeground()为您显示通知图标。

  2. 前台Service仍然可能被杀害,他们只是不太可能。

  3. 2.3中有一个错误(不知道它是否被修复),当一个ServiceonStartCommand()并重新启动时,它的onStartCommand()将不会被再次调用。 相反,你将不得不在onCreate()进行任何设置。

这两个代码仅在手机内存不足并在完成执行前杀死Service时才相关。 START_STICKY告诉操作系统在有足够的内存后重新创build服务,并以null意图再次调用onStartCommand()START_NOT_STICKY告诉操作系统不要再次重新创build服务。 还有第三个代码START_REDELIVER_INTENT告诉操作系统重新创buildService ,并将同样的意图重新传递给onStartCommand()

这篇由Dianne Hackborn 撰写的文章解释了这个比官方文档更好的背景。

这里的关键部分是由函数返回的一个新的结果代码,告诉系统如果它的进程在运行时被终止,它应该如何处理这个服务:

START_STICKY与之前的行为基本相同,在这种行为中,服务保持“启动”状态,稍后将由系统重新启动。 与以前版本的平台唯一的区别是,如果它因为进程被终止而重新启动,那么onStartCommand()将会在下一个具有null Intent的服务实例上被调用,而不是被调用。 使用这种模式的服务应该总是检查这种情况并适当地处理它。

START_NOT_STICKY表示,从onStartCreated()返回后,如果进程被终止而没有剩余的启动命令要交付,那么服务将被停止而不是重新启动。 这对于只在执行发送给它们的命令时才运行的服务更有意义。 例如,可以每15分钟从一个警报开始一个服务来轮询一些networking状态。 如果在做这件事的时候被杀死了,最好是让它停下来,然后在下一次警报起火的时候开始。

START_REDELIVER_INTENT与START_NOT_STICKY类似,除非服务进程在针对给定意图调用stopSelf()之前被终止,意图将被重新传递给它,直到它完成(除非经过多次尝试仍然无法完成,系统放弃)。 这对于接收工作命令的服务是有用的,并且要确保它们最终完成每个发送的命令的工作。