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

Mys*_*icϡ 52 android android-service

我有一点问题.

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

相关代码:

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

<service
    android:enabled="true"
    android:name=".MyService"
    android:exported="false"
    android:stopWithTask="false" />
Run Code Online (Sandbox Code Playgroud)

在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

public void onTaskRemoved(Intent rootIntent)

在API级别14中添加

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

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

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

我错过了什么吗?

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

PS:到目前为止我在4.2.2上测试了这个.

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

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

Avn*_*ary 31

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

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

    @Override
    public int onStartCommand(final Intent intent, 
                              final int flags,
                              final int startId) {
    
        //your code
        return START_STICKY;
    }  
    
    Run Code Online (Sandbox Code Playgroud)
  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);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 启动服务如下

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

  • 在使用onTaskRemoved()的解决方案中,我注意到该过程和服务正在重新启动。这意味着,流程和服务进入了几秒钟不完成工作的状态。但是,即使用户在最近的应用程序列表中向右滑动该应用程序,我也希望该服务和流程能够24 x 7运行。怎么做?请帮忙。 (2认同)

Sel*_*aza 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); 
}
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个解决方案,您的服务仍然被终止并重新启动,这在大多数情况下是不需要的。 (2认同)

naw*_*aab -4

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

    }
}
Run Code Online (Sandbox Code Playgroud)

或者

试试这个

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

}
Run Code Online (Sandbox Code Playgroud)

  • 当应用程序从任何地方被终止时,AlarmManager 就会被清除。所以这不是一个解决方案。 (14认同)
  • @UnityBeginner:如果我知道你在应用程序中使用它,我永远不会安装它。因为**你每一秒都在唤醒我的设备,而你就是我的电池耗尽的原因**。 (6认同)