Android的服务停止当应用程序被关闭

问题描述 投票:66回答:14

我开始从我的主要的Android活动相关的服务如下:

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

当我从最近的应用程序列表刷卡它关闭活动页面,服务一段时间后停止运行并重新启动。我不能因为我的应用程序要求的通知使用持久性服务。我怎样才能使服务无法重新启动或关机,只是不断在应用程序退出运行?

android service android-activity restart shutdown
14个回答
41
投票

我在同样的情况,到目前为止,我了解到,当应用程序被关闭的服务中获得也被关闭,因为他们是在一个线程,因此该服务应该是为了另一个线程FOT它不被关闭,看个明白并考虑保活在这里的报警管理器的示例服务http://www.vogella.com/articles/AndroidServices/article.html这样您的服务将不会显示通知。

最后,所有的研究后,我已经做了,我逐渐认识到,长期运行的服务的最佳选择是startForeground(),因为它是由为和系统实际上与服务交易良好。


1
投票

当你的进程被杀害,使得它处理的情况下,你必须在服务类中添加以下代码

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

0
投票

为什么不使用IntentService?

IntentService从主线程中打开一个新的线程分开,在那里工作,这种方式关闭的应用程序不会影响它

注意,IntentService运行onHandleIntent(),当它完成了服务关闭,看它是否符合您的需求。 http://developer.android.com/reference/android/app/IntentService.html


0
投票
<service android:name=".Service2"
            android:process="@string/app_name"
            android:exported="true"
            android:isolatedProcess="true"
            />

在您的清单中声明这一点。举一个自定义名称到您的进程,使这一进程隔离和出口。


0
投票

运行的意图的服务会更容易。服务创建应用程序中的线程,但它仍然在应用程序中。


-5
投票

只是覆盖的onDestroy方法在你第一次看到类似的活动后,溅你的主页,而从飞溅重定向到主页,你已经完成飞溅。所以把在主页破坏。在该方法停止服务。


12
投票

This可以帮助你。我可能是错了,但在我看来,这是在你的START_STICKY方法返回onStartCommand()有关。您可以通过返回START_NOT_STICKY而是避免被再次调用的服务。


12
投票

让您服务像这样在你的清单

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

那么你的服务将在其他工艺命名ServiceProcess运行


如果你想使你的服务永远不会死:

  1. onStartCommand()返回START_STICKY
  2. 的onDestroy() - >启动自
  3. 创建一个后台程序服务
  4. 斤 - >创建一个本地守护程序过程中,你可以找到在github上的一些开源项目
  5. startForeground(),有一个办法startForeground,恕不另行通知,谷歌,

3
投票

在无法启动服务时,应用程序关闭,Android操作系统(在某些OS)的主要问题将杀死服务资源优化配置,如果你不能够重新启动该服务,然后拨打报警马槽开始这样的reciver,这里是整个代码,这个代码将保持活跃乌尔服务。

货单,

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

在主要活动中启动报警经理以这种方式,

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

这将调用接收器和接收器,

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

当Android应用程序被打开,当应用程序是closed.SO服务是这样这样Alaram reciver再次呼吁,

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

3
投票

服务是相当复杂的,有时。

当您从一个活动(或流程)启动一个服务,该服务本质上是同一的过程。

从开发者的笔记报价

关于服务类最混乱实际上都是围绕着它不是什么:

A服务不是一个单独的过程。服务对象本身并不意味着它是在其自己的进程中运行;除非另有说明,它运行在相同的过程,因为它是的一部分的应用。

服务没有一个线程。它不是指本身做掉主线程的工作(以避免应用程序没有响应的错误)。

那么,这是什么意思是,如果用户扫描应用离最近的任务,它会删除你的进程(这包括所有的活动等)。现在,让我们三个场景。

首先在服务不具有前景的通知。

在这种情况下你的进程与服务一起遇难。

其次这里的服务有前景的通知

在这种情况下,服务是不是死亡,也不是过程

第三种情况如果服务没有前景的通知,它仍然可以继续运行,如果该应用程序被关闭。我们可以通过在不同的进程中运行的服务做到这一点。 (不过,我听到一些人说,它可能无法正常工作。留给你自己试试它了)

你可以通过在你的清单下面的属性创建一个单独的进程服务。

机器人:过程= “:yourService”

要么

机器人:工艺=“yourService”进程名称必须以小写字母开头。

从开发者备注报价

(“:”)如果分配给该属性的名称以冒号开始,一个新的进程,私有的应用程序,在需要时创建和服务在该进程中运行。如果进程名称以小写字母开头,该服务将在该名字的全局进程中运行,只要它具有这样的权限。这使得在不同应用程序的组件共享一个进程,减少资源的使用。

这是我收集的,如果任何人是专家,请你纠正我,如果我错了:)


3
投票

从Android的O,你不能使用长时间运行的后台操作服务,由于这一点,https://developer.android.com/about/versions/oreo/background。 Jobservice将与的jobscheduler实现更好的选择。


2
投票

试试这个,它会继续在后台运行的服务。

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

在您的MainActivity onCreate放弃这一行代码

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

现在,该服务将留在后台运行。


1
投票

最好的解决办法是使用同步适配器在android系统启动服务。创建一个同步适配器,并呼吁启动服务,在他们里面..方法onPerformSync。创建同步帐户,请参阅以下链接https://developer.android.com/training/sync-adapters/index.html

为什么SyncAdapter?答:因为你越早使用使用您的应用程序上下文来启动服务。因此,只要你的应用程序被打死(当u从任务管理器或操作系统中删除它杀死它的,因为缺乏资源),在那个时候你的服务也将被删除。除非ü编写代码来删除它SyncAdapter不会在应用程序线程工作..所以如果u调用里面..服务将不再被删除..。


1
投票

使用相同的过程在服务的服务和活动,START_STICKY或START_REDELIVER_INTENT是唯一的出路,以便能够重新启动该服务时,应用程序重新启动,当用户关闭例如应用程序,它会发生,而且当系统决定关闭它的优化的原因。你不能将永久运行没有任何中断的服务。这是由设计,智能手机不发运行的时间很长一段连续的过程。这是由于电池寿命是最高优先级。你需要因此处理在任何时候停止设计您服务。

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