Android Service Stops When App Is Closed

2019-01-02 23:16发布

I am starting a service from my main Android activity as follows:

final Context context = base.getApplicationContext();
final Intent intent = new Intent(context, MyService.class);
startService(intent);

When I close the activity page by swiping it out from the recent apps list, the service stops running and restarts after some time. I can't use persistent services with notifications because of my app requirements. How can I make the service NOT restart or shutdown and just keep on running on app exit?

13条回答
Juvenile、少年°
2楼-- · 2019-01-02 23:34

try this, it will keep the service running in the background.

BackServices.class

public class BackServices extends Service{

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
   public int onStartCommand(Intent intent, int flags, int startId) {
      // Let it continue running until it is stopped.
      Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
      return START_STICKY;
   }
   @Override
   public void onDestroy() {
      super.onDestroy();
      Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
   }
}

in your MainActivity onCreate drop this line of code

startService(new Intent(getBaseContext(), BackServices.class));

Now the service will stay running in background.

查看更多
戒情不戒烟
3楼-- · 2019-01-02 23:39

make you service like this in your Mainifest

 <service
            android:name=".sys.service.youservice"
            android:exported="true"
        android:process=":ServiceProcess" />

then your service will run on other process named ServiceProcess


if you want make your service never die :

  1. onStartCommand() return START_STICKY

  2. onDestroy() -> startself

  3. create a Deamon service

  4. jin -> create a Native Deamon process, you can find some open-source projects on github

  5. startForeground() , there is a way to startForeground without Notification ,google it

查看更多
小情绪 Triste *
4楼-- · 2019-01-02 23:43

This may help you. I may be mistaken but it seems to me that this is related with returning START_STICKY in your onStartCommand() method. You can avoid the service from being called again by returning START_NOT_STICKY instead.

查看更多
别忘想泡老子
5楼-- · 2019-01-02 23:44

You must add this code in your Service class so that it handles the case when your process is being killed

 @Override
    public void onTaskRemoved(Intent rootIntent) {
        Intent restartServiceIntent = new Intent(getApplicationContext(), this.getClass());
        restartServiceIntent.setPackage(getPackageName());

        PendingIntent restartServicePendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartServiceIntent, PendingIntent.FLAG_ONE_SHOT);
        AlarmManager alarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
        alarmService.set(
                AlarmManager.ELAPSED_REALTIME,
                SystemClock.elapsedRealtime() + 1000,
                restartServicePendingIntent);

        super.onTaskRemoved(rootIntent);
    }
查看更多
仙女界的扛把子
6楼-- · 2019-01-02 23:45

The Main problem in unable to start the service when app closed,android OS(In Some OS) will kill the service for Resource Optimization, If you are not able to restart the service then call a alarm manger to start the reciver like this,Here is the entire code,This code will keep alive ur service.

Manifest is,

         <service
            android:name=".BackgroundService"
            android:description="@string/app_name"
            android:enabled="true"
            android:label="Notification" />
        <receiver android:name="AlarmReceiver">
            <intent-filter>
                <action android:name="REFRESH_THIS" />
            </intent-filter>
        </receiver>

IN Main Activty start alarm manger in this way,

String alarm = Context.ALARM_SERVICE;
        AlarmManager am = (AlarmManager) getSystemService(alarm);

        Intent intent = new Intent("REFRESH_THIS");
        PendingIntent pi = PendingIntent.getBroadcast(this, 123456789, intent, 0);

        int type = AlarmManager.RTC_WAKEUP;
        long interval = 1000 * 50;

        am.setInexactRepeating(type, System.currentTimeMillis(), interval, pi);

this will call reciver and reciver is,

public class AlarmReceiver extends BroadcastReceiver {
    Context context;

    @Override
    public void onReceive(Context context, Intent intent) {
        this.context = context;

        System.out.println("Alarma Reciver Called");

        if (isMyServiceRunning(this.context, BackgroundService.class)) {
            System.out.println("alredy running no need to start again");
        } else {
            Intent background = new Intent(context, BackgroundService.class);
            context.startService(background);
        }
    }

    public static boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

        if (services != null) {
            for (int i = 0; i < services.size(); i++) {
                if ((serviceClass.getName()).equals(services.get(i).service.getClassName()) && services.get(i).pid != 0) {
                    return true;
                }
            }
        }
        return false;
    }
}

And this Alaram reciver calls once when android app is opened and when app is closed.SO the service is like this,

public class BackgroundService extends Service {
    private String LOG_TAG = null;

    @Override
    public void onCreate() {
        super.onCreate();
        LOG_TAG = "app_name";
        Log.i(LOG_TAG, "service created");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i(LOG_TAG, "In onStartCommand");
        //ur actual code
        return START_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Wont be called as service is not bound
        Log.i(LOG_TAG, "In onBind");
        return null;
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);
        Log.i(LOG_TAG, "In onTaskRemoved");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i(LOG_TAG, "In onDestroyed");
    }
}
查看更多
Anthone
7楼-- · 2019-01-02 23:47

Just override onDestroy method in your first visible activity like after splash you have home page and while redirecting from splash to home page you have already finish splash. so put on destroy in home page. and stop service in that method.

查看更多
登录 后发表回答