我在启动活动时启动服务(或重新启动正在运行的服务),使用:
Intent intent = new Intent(this, MyService.class);
startService(intent);
稍后基于某些操作,相同的活动使用
绑定到服务bindService(new Intent(this, MyService.class), mConnection, Context.BIND_AUTO_CREATE);
当活动被破坏时,我打电话给
unbindService(mConnection);
之前,当我从应用程序托盘中杀死相同的活动/应用程序并在运行的应用程序下显示“消息1进程1服务正在运行”时,该服务用于重新启动。
现在,服务不会在杀死相同的活动/应用程序时重新启动。
我收到消息“0进程1服务正在运行”,这意味着服务实际上没有运行。
在关闭应用程序时,服务不会重新启动。我的申请包含一项活动。在系统启动后启动时,服务也会成功启动。
为什么在使用startService()??
启动服务时,服务进程会被终止修改
我从应用程序托盘关闭应用程序后,用于重新启动的服务。但现在突然使用相同的代码,它没有。当我关闭它时,它也会与其他应用程序一起发生。例如。
答案 0 :(得分:51)
这是我遇到的一种解决方法,如果在关闭应用程序时它的进程被终止,则可以很好地重新启动服务。在您的服务中,添加以下代码。
我在this帖子中遇到了这种解决方法。
@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);
}
似乎是应用程序进程被杀死的错误。如果服务的进程被终止,服务就没有意义了。
答案 1 :(得分:6)
请注意: onDestroy并不总是被调用。你不应该这样放置代码。
当系统异常关闭或关闭活动时,onDestroy不会被调用。
答案 2 :(得分:4)
不幸的是,由于Android的工作方式,这是一个复杂的问题。有许多策略可以解决问题的不同部分。 为了获得最佳效果,请将多种策略结合使用。
请注意,在最近的Android版本中可能不再需要其中一些策略。
取自Foreground service killed when receiving broadcast after acitivty swiped away in task list:
在前台服务中:
@Override public void onTaskRemoved( Intent rootIntent ) { Intent intent = new Intent( this, DummyActivity.class ); intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK ); startActivity( intent ); }
在清单中:
<activity android:name=".DummyActivity" android:theme="@android:style/Theme.NoDisplay" android:enabled="true" android:allowTaskReparenting="true" android:noHistory="true" android:excludeFromRecents="true" android:alwaysRetainTaskState="false" android:stateNotNeeded="true" android:clearTaskOnLaunch="true" android:finishOnTaskLaunch="true" />
(如果您的服务处于不同的流程,请将此活动的流程设置为相同的流程。)
在DummyActivity.java中:
public class DummyActivity extends Activity { @Override public void onCreate( Bundle icicle ) { super.onCreate( icicle ); finish(); } }
使最近活动关闭。通常,刷掉应用程序并不会关闭最近的活动。
这只会生效when the dummy activity starts,这可能需要半秒或更长时间,所以这仍然可以使服务处于打开状态。
当您移除/滑动您的应用时,名为waitingToKill
的标记为set。设置此标记后,Android可能会终止进程{{3}},例如at any point in the future。开始活动when you receive a broadcast
BroadcastReceiver
将其合并到您的服务代码中:
if (Build.VERSION.SDK_INT >= 16) {
Intent intent = new Intent(this, DummyReceiver.class);
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
//This seems to be timing-related; the more times we do this,
//the less likely the process gets killed
for (int i = 0; i < 50; ++i)
sendBroadcast(intent);
}
创建虚拟广播接收器:
public class DummyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {}
}
将接收器添加到清单中:
<receiver android:name=".DummyReceiver" />
从最近屏幕移除任务时,可能会导致轻微(~250ms)延迟/挂起。
这只会在接收广播时使进程保持活动状态。 foreground broadcasts标志仍然设置,因此之后可能仍然会杀死该进程,例如收到广播时。
如果您的流程未以前台优先级waitingToKill
运行。接收前台广播会暂时阻止此操作,从而导致设置Android will try to kill it immediately标志。
答案 3 :(得分:1)
我知道这个问题已经过时但我最近遇到了这个问题,突然我的服务在关闭应用时停止了。早些时候它工作正常。这个问题浪费了我很多时间。对于有类似问题的其他人,请确保您的背景数据限制已关闭。 这是我遇到的问题,它实际上是有道理的,因为后台数据是受限制的后台进程将无法运行。
答案 4 :(得分:1)
onDestroy并不总是被调用。你的情况下的主要问题是当app关闭时你无法启动服务,那时android OS( In Some OS )将会杀死服务,如果你无法重启服务,那就打电话给警报管理员来启动这样的接收器,
清单是,
<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以这种方式启动报警管理器,
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);
这将调用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应用程序并关闭应用程序时,这个Alaram会调用一次。服务是这样的,
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");
}
}
答案 5 :(得分:-1)
当没有绑定到服务或已建立的前景时,android系统会将该服务识别为应该关闭的未使用的重载服务。即使应用已关闭,以下是维持服务的最佳方式:AlarmManager or Service