即使从最近的应用程序中清除了应用程序,也继续服务 [英] Continue Service even if application is cleared from Recent app

查看:30
本文介绍了即使从最近的应用程序中清除了应用程序,也继续服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个小问题.

在我的应用程序中,用户成功登录后启动了一个服务.以前,如果应用程序被终止,服务需要停止.(比如说,通过滑动从最近的应用程序列表中删除.)所以我们使用了 android:stopWithTask="true".现在我们需要服务按原样运行,即使启动它的任务从最近的应用程序列表中删除.所以我将服务更改为包含 android:stopWithTask="false".但这似乎不起作用.

相关代码:

这是与服务相关的清单部分:

<服务机器人:启用=真"android:name=".MyService"机器人:出口=假"android:stopWithTask="false"/>

在 MyService.java 中:

public class MyService extends AbstractService {@覆盖公共无效 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);通知通知 = new Notification(R.drawable.ic_launcher, "我的网络服务", System.currentTimeMillis());notification.setLatestEventInfo(this, "AppName", "Message", pendingIntent);startForeground(MY_NOTIFICATION_ID,通知);}@覆盖public void onTaskRemoved(Intent rootIntent) {Toast.makeText(getApplicationContext(), "onTaskRemoved called", Toast.LENGTH_LONG).show();System.out.println("onTaskRemoved 调用");super.onTaskRemoved(rootIntent);}}

AbstractService.java 是扩展 Service 的自定义类:

公共抽象类 AbstractService 扩展服务 {受保护的最终字符串 TAG = this.getClass().getName();@覆盖公共无效 onCreate() {super.onCreate();onStartService();Log.i(TAG, "onCreate(): Service Started.");}@覆盖public final int onStartCommand(Intent Intent, int flags, int startId) {Log.i(TAG, "onStarCommand(): Received id " + startId + ": " + intent);返回 START_STICKY;//运行直到明确停止.}@覆盖公共最终 IBinder onBind(意图意图){返回 m_messenger.getBinder();}@覆盖公共无效 onDestroy() {super.onDestroy();onStopService();Log.i(TAG, "服务停止.");}公共抽象无效 onStartService();公共抽象无效 onStopService();公共抽象无效 onReceiveMessage(Message msg);@覆盖public void onTaskRemoved(Intent rootIntent) {Toast.makeText(getApplicationContext(), "AS onTaskRemoved called", Toast.LENGTH_LONG).show();super.onTaskRemoved(rootIntent);}}

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

<块引用>

public void onTaskRemoved (Intent rootIntent)

在 API 级别 14 中添加

如果服务当前正在运行并且用户有删除了来自服务应用程序的任务.如果你有设置 ServiceInfo.FLAG_STOP_WITH_TASK 那么你将不会收到这个打回来;相反,该服务将被简单地停止.

参数 rootIntent 用于启动被移除的任务.

但我没有看到任何这些.服务在 onStartCommand 中返回 START_STICKY,所以我认为 onTaskRemoved 应该与标志 android:stopWithTask="false" 一起被触发.

我错过了什么吗?

如果我需要添加一些可能对找出问题很重要的代码,请告诉我.

P.S.:到目前为止,我在 4.2.2 上对此进行了测试.

P.S.:我刚刚在 4.1.2 中测试了相同的代码,在该代码上 Service 继续运行,并且我在日志中也收到消息onTaskRemoved called".

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

解决方案

只需遵循这些方案,您的服务和进程(在您的服务中运行的线程)将保持连续.

  1. 创建服务并在 onStartCommand 方法中使用 START_STICKY 作为返回值,如下所示:

    @Overridepublic int onStartCommand(最终意图意图,最终的 int 标志,最终 int startId) {//你的代码返回 START_STICKY;}

  2. 如果您的应用程序从最近的应用程序中删除,上面的代码将重新启动服务,如果被破坏并始终保持运行,但从服务运行的进程(线程)将停止工作.为了确保您的进程(线程)始终处于运行状态,您必须覆盖 onTaskRemoved() 方法并添加代码以重新启动任务,如下所示.

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

I am having a little issue.

In my application, a Service is started after user is logged in successfully. Previously, the service needed to stop if application was killed. (say, removed from Recent application list by swiping.) So we had used android:stopWithTask="true". Now we need the Service to run as it is, even if the Task which started it, is removed from Recent app list. So I changed the Service to include android:stopWithTask="false". But that doesn't seem to work.

Related code:

Here is manifest part related to Service:

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

In 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 is custom class that extends 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);
    }
}

Now if I login in the application, MyService is started. After that I press Home button, so application is moved to background. Now I remove the application from Recent Application's list. At that time, I should see the Toast and console message, as per this method's description:

public void onTaskRemoved (Intent rootIntent)

Added in API level 14

This is called if the service is currently running and the user has removed a task that comes from the service's application. If you have set ServiceInfo.FLAG_STOP_WITH_TASK then you will not receive this callback; instead, the service will simply be stopped.

Parameters rootIntent The original root Intent that was used to launch the task that is being removed.

But I am not seeing any of that. Service is returning START_STICKY in onStartCommand, So I think onTaskRemoved should be fired along with flag android:stopWithTask="false".

Am I missing anything?

Let me know in case I need to add some code which might be important to figure out what's wrong.

P.S.: I tested this on 4.2.2 till now.

P.S.: I just tested the same code in 4.1.2, on which Service keeps running, and I get the message "onTaskRemoved called" in log, too.

What should I do to make this work in all versions?

解决方案

Just follow these scenarios, your service and processes (Threads run inside your service) will remain continuous.

  1. Create service and use START_STICKY as return value in onStartCommand method like below:

    @Override
    public int onStartCommand(final Intent intent, 
                              final int flags,
                              final int startId) {
    
        //your code
        return START_STICKY;
    }  
    

  2. Above code will Restart the service if destroyed and always remain running but the process(Threads) run from the service will stop working if your app is removed from the recent apps. To ensure that your processes(Threads) remains always in running condition you have to Override onTaskRemoved() method and add code to restart Tasks like below.

    @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. Start service like below

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

这篇关于即使从最近的应用程序中清除了应用程序,也继续服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆