关闭应用程序时防止服务/Activity被杀死
Prevent a Service / Activity been killed when closing the application
这几天我一直在想办法解决这个问题。
我有一个 Android 应用程序,它实际上由一个简单的 WebView 和一个 start/stop 服务按钮组成。该服务启动一个任务(每 60 秒)检查是否有任何更新(调用外部 PHP 函数),如果有,它会显示一个通知。
我还有一个BroadcastReceiver被服务的“onTaskRemoved”函数调用(我也试过从onDestroy中调用BroadcastReceiver,但是结果是一样的), 关闭时重启服务。
后台服务在应用程序打开时工作正常;当我关闭它时,“onTaskRemoved”调用重新启动服务的 BroadcastReceiver,它仍然可以工作几分钟(每次更改多长时间)。几分钟后,检查更新的任务停止工作,我在日志中读到的唯一消息是 Activity 已被杀死(收到的最后一条消息是 "01-09 15:03:34.593 4306 5082 I ActivityManager: Killing 13691:com.xxx.xxx/u0a262 (adj 906): DHA:SPC_empty #31", 但基于我在做的许多研究中读到的内容,服务应该继续 运行,我错了吗?
下面是部分代码:
start/stop main class 中的服务的 Button Click 侦听器:
btn.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
if (btn.getText().equals("Start Monitoring"))
{
mMonitoringService = new MonitoringService(getCtx());
mServiceIntent = new Intent(getCtx(), mMonitoringService.getClass());
if (!isMyServiceRunning(mMonitoringService.getClass())) {
startService(mServiceIntent);
}
btn.setText("Stop Monitoring");
...
}
else
{
mMonitoringService = new MonitoringService(getCtx());
if (isMyServiceRunning(mMonitoringService.getClass())) {
mServiceIntent = new Intent(getCtx(), mMonitoringService.getClass());
stopService(mServiceIntent);
}
btn.setText("Start Monitoring");
...
}
}
});
服务:
public class MonitoringService extends Service {
Context mContext;
private long lastCheck = System.currentTimeMillis() - 6000044;
public MonitoringService(Context applicationContext, String UsrCookie) {
super();
mContext = applicationContext;
Log.i("SERVICE", "here I am!");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (intent != null)
{
Log.d("Intent","not null");
startMyTimer(mContext);
}
else{
Log.d("Intent","null");
}
return START_STICKY;
}
@Override
public void onDestroy(){
super.onDestroy();
Log.i("EXIT", "onDestroy!");
}
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i("EXIT", "onTaskRemoved!");
Intent broadcastIntent = new Intent("com.xxx.xxx.ActivityRecognition.RestartMonitoring");
broadcastIntent.setClass(this,MonitoringRestarterBroadcastReceiver.class);
sendBroadcast(broadcastIntent);
stopMyTimertask();
}
public void startMyTimer(Context inContext) {
//set a new Timer
myTimer = new Timer();
//initialize the TimerTask's job
initializeMyTimerTask(inContext);
//schedule the timer, to wake up every 0.1 second
myTimer.schedule(myTimerTask, 100, 100); //
}
public void initializeMyTimerTask(final Context inContext) {
Log.i("DPCLite", "initializeMyTimerTask");
myTimerTask = new TimerTask() {
public void run() {
try {
Long nowDate = System.currentTimeMillis();
if (((nowDate - lastCheck) / 1000) > 60 && isNetworkAvailable())
{
lastCheck = nowDate;
callPHPfunction(inContext);
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
public void stopMyTimertask() {
//stop the timer, if it's not already null
if (myTimer != null) {
Log.i("stopMyTimertask", "STOPPED");
myTimer.cancel();
myTimer = null;
}
}
和 BroadcastReceiver:
public class MonitoringRestarterBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(MonitoringRestarterBroadcastReceiver.class.getSimpleName(), "Service Stopped!");
Intent newIntent = new Intent(context, MonitoringService.class);
context.startService(newIntent);
}
}
已解决。
经过如此多的调试,我发现在 Android 7.0 的三星上,有时服务的重新启动带有 intent null,所以实际上服务仍然是 运行 但不是我的任务。
这几天我一直在想办法解决这个问题。
我有一个 Android 应用程序,它实际上由一个简单的 WebView 和一个 start/stop 服务按钮组成。该服务启动一个任务(每 60 秒)检查是否有任何更新(调用外部 PHP 函数),如果有,它会显示一个通知。
我还有一个BroadcastReceiver被服务的“onTaskRemoved”函数调用(我也试过从onDestroy中调用BroadcastReceiver,但是结果是一样的), 关闭时重启服务。
后台服务在应用程序打开时工作正常;当我关闭它时,“onTaskRemoved”调用重新启动服务的 BroadcastReceiver,它仍然可以工作几分钟(每次更改多长时间)。几分钟后,检查更新的任务停止工作,我在日志中读到的唯一消息是 Activity 已被杀死(收到的最后一条消息是 "01-09 15:03:34.593 4306 5082 I ActivityManager: Killing 13691:com.xxx.xxx/u0a262 (adj 906): DHA:SPC_empty #31", 但基于我在做的许多研究中读到的内容,服务应该继续 运行,我错了吗?
下面是部分代码:
start/stop main class 中的服务的 Button Click 侦听器:
btn.setOnClickListener( new View.OnClickListener() {
@Override
public void onClick(View v) {
if (btn.getText().equals("Start Monitoring"))
{
mMonitoringService = new MonitoringService(getCtx());
mServiceIntent = new Intent(getCtx(), mMonitoringService.getClass());
if (!isMyServiceRunning(mMonitoringService.getClass())) {
startService(mServiceIntent);
}
btn.setText("Stop Monitoring");
...
}
else
{
mMonitoringService = new MonitoringService(getCtx());
if (isMyServiceRunning(mMonitoringService.getClass())) {
mServiceIntent = new Intent(getCtx(), mMonitoringService.getClass());
stopService(mServiceIntent);
}
btn.setText("Start Monitoring");
...
}
}
});
服务:
public class MonitoringService extends Service {
Context mContext;
private long lastCheck = System.currentTimeMillis() - 6000044;
public MonitoringService(Context applicationContext, String UsrCookie) {
super();
mContext = applicationContext;
Log.i("SERVICE", "here I am!");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if (intent != null)
{
Log.d("Intent","not null");
startMyTimer(mContext);
}
else{
Log.d("Intent","null");
}
return START_STICKY;
}
@Override
public void onDestroy(){
super.onDestroy();
Log.i("EXIT", "onDestroy!");
}
@Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i("EXIT", "onTaskRemoved!");
Intent broadcastIntent = new Intent("com.xxx.xxx.ActivityRecognition.RestartMonitoring");
broadcastIntent.setClass(this,MonitoringRestarterBroadcastReceiver.class);
sendBroadcast(broadcastIntent);
stopMyTimertask();
}
public void startMyTimer(Context inContext) {
//set a new Timer
myTimer = new Timer();
//initialize the TimerTask's job
initializeMyTimerTask(inContext);
//schedule the timer, to wake up every 0.1 second
myTimer.schedule(myTimerTask, 100, 100); //
}
public void initializeMyTimerTask(final Context inContext) {
Log.i("DPCLite", "initializeMyTimerTask");
myTimerTask = new TimerTask() {
public void run() {
try {
Long nowDate = System.currentTimeMillis();
if (((nowDate - lastCheck) / 1000) > 60 && isNetworkAvailable())
{
lastCheck = nowDate;
callPHPfunction(inContext);
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
public void stopMyTimertask() {
//stop the timer, if it's not already null
if (myTimer != null) {
Log.i("stopMyTimertask", "STOPPED");
myTimer.cancel();
myTimer = null;
}
}
和 BroadcastReceiver:
public class MonitoringRestarterBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(MonitoringRestarterBroadcastReceiver.class.getSimpleName(), "Service Stopped!");
Intent newIntent = new Intent(context, MonitoringService.class);
context.startService(newIntent);
}
}
已解决。 经过如此多的调试,我发现在 Android 7.0 的三星上,有时服务的重新启动带有 intent null,所以实际上服务仍然是 运行 但不是我的任务。