当应用程序关闭时,Android服务停止
我正在从我的主要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); 当我通过从“最近使用的应用”列表中刷出活动页面来关闭该页面时,该服务将停止运行,并在一段时间后重新启动。由于我的应用程序要求,我无法使用带有通知的持久服务。如何使服务
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的进程上运行
如果您想让您的服务永不磨灭:
主要问题是当应用程序关闭时无法启动服务,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);
}