即使应用程序从最近的应用程序中清除,仍然继续服

我有一个小问题。

在我的应用程序中,服务在用户login成功后启动。 以前,如果应用程序被杀,服务需要停止。 (比如说,通过滑动从最近的应用程序列表中删除)。所以我们使用了android:stopWithTask="true" 。 现在我们需要服务运行,即使启动它的任务已经从最近的应用程序列表中删除。 所以我改变了服务,包括android:stopWithTask="false" 。 但是这似乎并不奏效。

相关代码:

这是与服务有关的明显部分:

 <service android:enabled="true" android:name=".MyService" android:exported="false" android:stopWithTask="false" /> 

在MyService.java中:

 public class MyService extends AbstractService { @Override public void onStartService() { Intent intent = new Intent(this, MyActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0); Notification notification = new Notification(R.drawable.ic_launcher, "My network services", System.currentTimeMillis()); notification.setLatestEventInfo(this, "AppName", "Message", pendingIntent); startForeground(MY_NOTIFICATION_ID, notification); } @Override public void onTaskRemoved(Intent rootIntent) { Toast.makeText(getApplicationContext(), "onTaskRemoved called", Toast.LENGTH_LONG).show(); System.out.println("onTaskRemoved called"); super.onTaskRemoved(rootIntent); } } 

AbstractService.java是扩展Sevrice自定义类:

 public abstract class AbstractService extends Service { protected final String TAG = this.getClass().getName(); @Override public void onCreate() { super.onCreate(); onStartService(); Log.i(TAG, "onCreate(): Service Started."); } @Override public final int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStarCommand(): Received id " + startId + ": " + intent); return START_STICKY; // run until explicitly stopped. } @Override public final IBinder onBind(Intent intent) { return m_messenger.getBinder(); } @Override public void onDestroy() { super.onDestroy(); onStopService(); Log.i(TAG, "Service Stopped."); } public abstract void onStartService(); public abstract void onStopService(); public abstract void onReceiveMessage(Message msg); @Override public void onTaskRemoved(Intent rootIntent) { Toast.makeText(getApplicationContext(), "AS onTaskRemoved called", Toast.LENGTH_LONG).show(); super.onTaskRemoved(rootIntent); } } 

现在,如果我在应用程序中login,MyService就会启动。 之后,我按主页button,所以应用程序被移动到后台。 现在我从最近的应用程序的列表中删除应用程序。 那时,我应该看到Toast和控制台消息,按照这个方法的描述:

public void onTaskRemoved(Intent rootIntent)

在API级别14中添加

如果服务当前正在运行,并且用户已经从服务的应用程序中删除了一个任务,则调用此方法。 如果你已经设置ServiceInfo.FLAG_STOP_WITH_TASK,那么你将不会收到这个callback; 相反,服务将被简单地停止。

参数rootIntent用于启动要删除的任务的原始根目录。

但是我没有看到这一点。 服务正在onStartCommand返回START_STICKY,所以我认为onTaskRemoved应该与标志android:stopWithTask="false"一起被解雇。

我错过了什么?

让我知道,如果我需要添加一些可能是重要的代码来弄清楚什么是错的。

PS:我在4.2.2上testing了这个。

PS:我只是在4.1.2中testing了相同的代码,在哪个Service继续运行,我也在日志中收到了消息“onTaskRemoved called”。

我应该怎么做才能在所有版本中工作?

只要按照这些scheme,您的服务和stream程(线程运行在您的服务中)将保持连续。

  1. 创build服务,并在下面的onStartCommand方法中使用START_STICKY作为返回值

      @Override public int onStartCommand(final Intent intent, final int flags, final int startId) { //your code return START_STICKY; } 
  2. 上面的代码将重新启动服务,如果销毁,并始终保持运行,但从服务运行的进程(线程)将停止工作,如果你的应用程序从最近的应用程序中删除。 为了确保你的进程(线程)始终处于运行状态,你必须重写onTaskRemoved()方法并添加代码来重启下面的任务。

     @Override public void onTaskRemoved(Intent rootIntent){ Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass()); restartServiceTask.setPackage(getPackageName()); PendingIntent restartPendingIntent =PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT); AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE); myAlarmService.set( AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartPendingIntent); super.onTaskRemoved(rootIntent); } 
  3. 开始像下面的服务

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

在您的服务中,添加以下代码。 4.4.2对我来说很好

这是我遇到的一种解决方法,如果在closures应用程序时终止了进程,则可以重新启动服务。

  @Override public void onTaskRemoved(Intent rootIntent){ Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass()); PendingIntent restartServicePendingIntent = PendingIntent.getService( getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT); AlarmManager alarmService = (AlarmManager) getSystemService(Context.ALARM_SERVICE); alarmService.set(ELAPSED_REALTIME, elapsedRealtime() + 1000, restartServicePendingIntent); super.onTaskRemoved(rootIntent); } 

如果您从Application类的子类绑定到您的服务并保留到您的IBinder连接,即使将应用程序从最近的应用程序中删除,该服务仍将保持活动状态。

看来,从“最近的任务”中删除一个应用程序会导致所有的问题。

也许你应该看看那里find一种方法来重新启动服务,如果它停止: https : //stackoverflow.com/a/22464640/4232337

写下我在服务类的oncreate()中添加的5行

喜欢这个:

 public class AlarmService extends Service { @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); Intent iHeartBeatService = new Intent(AlarmService.this, AlarmService.class); PendingIntent piHeartBeatService = PendingIntent.getService(this, 0, iHeartBeatService, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); alarmManager.cancel(piHeartBeatService); alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000, piHeartBeatService); } } 

要么

试试这个

 public class MyService extends Service{ @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); System.out.println("service created"); } @SuppressLint("NewApi") @Override public void onTaskRemoved(Intent rootIntent) { // TODO Auto-generated method stub System.out.println("onTaskRemoved"); super.onTaskRemoved(rootIntent); } @Override @Deprecated public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub super.onStart(intent, startId); System.out.println("Service started"); new Handler().postDelayed(new Runnable() { @Override public void run() { // TODO Auto-generated method stub System.out.println("Service is running"); } }, 5000); } }