即使从最近的应用程序中清除了应用程序,也要继

问题描述 投票:49回答:5

我有一点问题。

在我的应用程序中,在用户成功登录后启动服务。以前,如果应用程序被杀,该服务需要停止。 (比如,通过滑动从最近的应用程序列表中删除。)所以我们使用了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);
    }
}

现在,如果我登录应用程序,MyService就会启动。之后我按Home键,因此应用程序移动到后台。现在我从Recent Application的列表中删除该应用程序。那时,我应该看到Toast和console消息,按照这个方法的描述:

public void onTaskRemoved(Intent rootIntent)

在API级别14中添加

如果服务当前正在运行且用户已从服务的应用程序中删除了任务,则会调用此方法。如果您已设置ServiceInfo.FLAG_STOP_WITH_TASK,那么您将不会收到此回调;相反,该服务将被停止。

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

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

我错过了什么吗?

让我知道,以防我需要添加一些代码,这些代码可能对于弄清楚什么是错误很重要。

P.S。:我在4.2.2测试了这个到现在为止。

P.S。:我刚刚在4.1.2中测试了相同的代码,服务一直在运行,我在日志中也得到了“onTaskRemoved called”的消息。

我该怎么做才能在所有版本中使用它?

android android-service
5个回答
31
投票

只需按照这些方案,您的服务和流程(在您的服务中运行的线程)将保持连续。

  1. 创建服务并在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));


8
投票

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

这是我遇到的一种解决方法,如果在关闭应用程序时它的进程被终止,则可以很好地重新启动服务。

 @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); 
}

1
投票

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


-2
投票

似乎将应用程序从“最近的任务”中删除可以杀死所有附加的内容。

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


-3
投票

写下我在服务类的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);
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.