Java 我的Android服务赢得了';我不能一直跑
我有一个执行AsyncTask的服务,它在每次完成后调用自己。正如你在下面看到的,我正在前台开始我的服务。它成功启动并按预期运行,同时我将其插入计算机并将输出输出到LogCat。我知道这一点,因为为了测试,我让AsyncTask循环每5分钟发出一次通知。然而,当我把它从我的电脑上拔下时,通知就不来了!这就好像在我启动服务后,服务就完全停止了 注意:我的服务是常规服务,不是意向服务 这是我的启动命令Java 我的Android服务赢得了';我不能一直跑,java,android,android-intent,android-asynctask,android-service,Java,Android,Android Intent,Android Asynctask,Android Service,我有一个执行AsyncTask的服务,它在每次完成后调用自己。正如你在下面看到的,我正在前台开始我的服务。它成功启动并按预期运行,同时我将其插入计算机并将输出输出到LogCat。我知道这一点,因为为了测试,我让AsyncTask循环每5分钟发出一次通知。然而,当我把它从我的电脑上拔下时,通知就不来了!这就好像在我启动服务后,服务就完全停止了 注意:我的服务是常规服务,不是意向服务 这是我的启动命令 @SuppressWarnings("deprecation") @Override public
@SuppressWarnings("deprecation")
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
getData(intent);
self = this;
// Enter foreground state
String title = "Service started.";
String subject = "Service is running.";
String body = "Monitoring...";
Notification notification = new Notification(R.drawable.ic_launcher, title,
System.currentTimeMillis());
if(notificationSounds)
notification.defaults |= Notification.DEFAULT_SOUND;
else
notification.sound = null;
Intent notificationIntent = new Intent(this, MainActivity3.class);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, subject, body, pendIntent);
startForeground(1500, notification);
new BatteryLifeTask(appContext).execute();
return START_NOT_STICKY;
}
以下是我的任务:
// Looping AsyncTask for continuous mode
private class BatteryLifeTask extends AsyncTask<Void, Void, Void> {
// Member variables
Context appContext;
int batteryPct0;
public BatteryLifeTask(Context context) {
super();
appContext = context;
}
protected Void doInBackground(Void... params) {
System.out.println("Entering doInBackground");
// Get the initial battery level
batteryPct0 = getBatteryPercent();
System.out.println("Initial battery percent: " + batteryPct0);
// Check time
Calendar c = Calendar.getInstance();
Date dateNow = c.getTime();
// getTime returns ms, need minutes. 60000ms in a minute.
long currTime = dateNow.getTime() / 60000;
if(currTime >= timeToUse){
finished = true;
stopSelf();
}
System.out.println("Leaving doInBackground");
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(!finished) {
int waitTime = 60000 * interval; // 1 minute is 60000 miliseconds
System.out.println("Entering postExecute. waitTime is " + waitTime);
Runnable r = new Runnable() {
@Override
public void run() {
if(!finished) { // In case postDelayed is pending, avoids extra notification
System.out.println("An interval has passed.");
calculateHelper(batteryPct0);
new BatteryLifeTask(appContext).execute();
}
}
};
Handler h = new Handler();
h.postDelayed(r, waitTime);
}
}
}
有人能帮我吗?这快把我逼疯了!我的应用程序在插入并连接到USB调试时工作正常。但当拔下插头时,服务似乎完全停止,什么也不做。这是因为您正在使用服务返回 启动\u不粘如果 服务的进程在启动时(从返回后)被终止 onStartCommand(Intent,int,int)),并且没有新的启动意图 要交付给它,则将服务从启动状态中移除,然后 在将来显式调用之前不要重新创建 Context.startService(Intent) 你应该回来 START\u STICKY如果此服务的进程在启动时被终止(从onStartCommand(Intent,int,int)返回后),则 将其保持在started状态,但不要保留此交付意图。 稍后,系统将尝试重新创建服务
检查此项,尤其是服务生命周期更改部分。返回
START\u STICKY
,而不是START\u NOT\u STICKY
,然后检查您的设计。在您的情况下,最好使用具有5分钟超时的AlarmManager,然后启动IntentService。不相关,但您可以使用@njzk2,而不是//1分钟等于60000毫秒
,谢谢,这很有帮助。使用alarmmanager做什么?这有什么帮助?@njzk2是对的:AlarmManager
是一种方法,而不是这种循环AsyncTask
:@shkschneider异步任务是否进入睡眠状态/它是否会被操作系统杀死?我需要它不间断地无限期运行。AlarmManager可以帮我完成吗?我的应用程序中的等待时间可以设置为3小时。设计的一部分是在3小时开始时和3小时结束时获得电池电量,并找出差异,以便在该时间间隔内使用电池。这是预测算法的一部分。这5分钟的超时会干扰吗?可以随意设置alarm manager超时,但可以使用alarm manager设置计时器并对其进行管理。通过这种方式,您可以避免任何电池耗电。您可以提供一个使用alarmmanager完成任务的示例吗?此外,它是否具有预执行/后执行功能?我需要在postExecute中的代码之前执行和完成当前在doInBackground中的代码。我看到AsyncTask有这个功能,这就是为什么我选择在我的设计中使用它。docs:通过alarm manager,系统会向你的应用程序发送一个意向,当超时过期时,你可以用广播接收器捕捉到它,然后你可以启动一个意向服务。intentservice在后台工作,因此您无需担心任何事情。其他注意事项:您的设计是错误的,因为CPU可以在没有唤醒锁的情况下进入深度睡眠,但您确实不希望这样,否则会耗尽用户电池,因此请使用报警管理器。
// Method for creating a notification
@SuppressWarnings("deprecation")
void notify0(int id, String title, String subject, String body, boolean playSound){
NotificationManager NM = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notify = new Notification(android.R.drawable.
PendingIntent pending = PendingIntent.getActivity(
getApplicationContext(), 0, new Intent(), 0);
notify.setLatestEventInfo(getApplicationContext(), subject, body, pending);
if(playSound)
notify.defaults |= Notification.DEFAULT_SOUND;
else
notify.sound = null;
// Cancel running notification if exists
NM.cancel(id);
// Push notification
NM.notify(id, notify);
}