当应用程序关闭时,Android服务停止

当应用程序关闭时,Android服务停止,android,service,android-activity,restart,shutdown,Android,Service,Android Activity,Restart,Shutdown,我正在从我的主要Android活动启动一项服务,如下所示: final Context context = base.getApplicationContext(); final Intent intent = new Intent(context, MyService.class); startService(intent); 当我通过从“最近使用的应用”列表中刷出活动页面来关闭该页面时,该服务将停止运行,并在一段时间后重新启动。由于我的应用程序要求,我无法使用带有通知的持久服务。如何使服务

我正在从我的主要Android活动启动一项服务,如下所示:

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

当我通过从“最近使用的应用”列表中刷出活动页面来关闭该页面时,该服务将停止运行,并在一段时间后重新启动。由于我的应用程序要求,我无法使用带有通知的持久服务。如何使服务不重新启动或关闭,并在应用程序退出时继续运行?

可能会对您有所帮助。我可能弄错了,但在我看来,这与在
onStartCommand()
方法中返回
START\u STICKY
有关。你可以通过返回
START\u NOT\u STICKY
来避免再次调用该服务。

我也遇到了同样的情况,到目前为止,我了解到当应用程序关闭时,服务也会关闭,因为它们处于一个线程中,所以该服务应该位于另一个线程中,以便不被关闭,看看这一点,看看如何使用alarm manager使服务保持活动状态。这里是一个这样的示例,您的服务不会显示在通知中


最后,在我做了所有的研究之后,我逐渐意识到,对于长期运行的服务来说,最好的选择是,因为它是为这一点而设计的,而且系统实际上可以很好地处理您的服务。

试试这个,它会让服务在后台运行

后台服务类

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();
   }
}
main活动中
onCreate
删除这行代码

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

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

为什么不使用IntentService

IntentService在主线程之外打开一个新线程并在那里工作,这样关闭应用程序不会影响它

请注意,IntentService运行onHandleIntent(),完成后,服务将关闭,查看它是否符合您的需要。

只需在您的第一个可见活动中覆盖onDestroy方法,比如在splash之后您有了主页,而在从splash重定向到主页时,您已经完成了splash。所以在主页上放上destroy。并停止该方法中的服务

让您在Mainifest中像这样服务

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

然后,您的服务将在另一个名为ServiceProcess的进程上运行


如果您想让您的服务永不磨灭:

  • onStartCommand()返回START\u

  • onDestroy()->startself

  • 创建一个执事服务

  • jin->创建一个本地Deamon流程,您可以在github上找到一些开源项目

  • startForeground(),有一种方法可以在没有通知的情况下启动startForeground,用谷歌搜索它


  • 主要问题是当应用程序关闭时无法启动服务,android操作系统(在某些操作系统中)将停止服务以优化资源,如果您无法重新启动服务,请调用报警管理器以这样启动接收器,这是完整的代码,此代码将保持服务的活动状态

    清单是

             <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>
    
    这将调用reciver,reciver是

    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中的同步适配器启动服务。创建同步适配器并调用启动服务。。内部onPerformSync方法。要创建同步帐户,请参阅此链接

    为什么要同步适配器?答:因为之前您使用应用程序上下文启动服务。因此,每当你的应用程序进程被终止时(当你从任务管理器中删除它或操作系统因为资源不足而终止它时),你的服务也将被删除。SyncAdapter将无法在应用程序线程中工作。。所以如果你在里面打电话。。服务将不再被删除。。除非你写代码删除它

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

    在你的舱单上声明这一点。为流程指定自定义名称,并使该流程隔离并导出

    对服务和活动使用相同的流程,并在服务中使用START_STICKY或START_REDELIVER_INTENT是在应用程序重新启动时能够重新启动服务的唯一方法,例如,当用户关闭应用程序时,以及当系统出于优化原因决定关闭应用程序时,都会发生这种情况。你不能有一个服务,将永久运行没有任何中断。这是在设计上,智能手机不是为了长时间连续运行的。这是因为电池寿命是最高优先级。您需要设计您的服务,使其能够处理在任何时候停止的情况。

    服务有时相当复杂

    从活动(或流程)启动服务时,服务基本上位于同一流程上

    引用开发商注释

    关于服务类的大多数困惑实际上围绕着它不是什么:

    服务不是一个单独的进程。服务对象本身并不意味着它正在自己的进程中运行;除非另有规定,否则它与它所属的应用程序在同一进程中运行

    服务不是线程。它本身并不是一种脱离主线程工作的方法(以避免应用程序不响应错误)

    因此,这意味着,如果用户将应用程序从最近的任务中删除,它将删除您的进程(包括您的所有活动等)。 现在,让我们看三个场景

    首先服务没有前台通知

    在这种情况下,进程将与服务一起终止

    第二个服务具有前台通知的位置

    在这种情况下,服务不会终止,进程也不会终止

    第三种情景 如果该服务没有前台通知,则在应用程序关闭时仍可以继续运行。我们可以通过使服务在不同的进程中运行来实现这一点。 (然而,我听到一些人说它可能不起作用。让你自己试试看)

    通过包含以下属性,可以在单独的流程中创建服务 在你的舱单上

    android:进程
    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");
        }
    }
    
    <service android:name=".Service2"
                android:process="@string/app_name"
                android:exported="true"
                android:isolatedProcess="true"
                />
    
     @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);
        }