我正在尝试保持对屏幕开/关更改做出反应的服务。该服务将在一段时间内运行良好,但最终将被终止。我现在正尝试使用startForeground()来保持该进程运行,但是它似乎仍在消亡。我知道没有办法可以使进程永远存活,没有错误,但是我觉得我一定做错了,因为添加startForeground()不会增加进程的寿命。另外,作为旁注,由于未调用unregisterReceiver()(除非通过用户手动按下按钮进行手动操作),Logcat抱怨存在泄漏。.但是,由于我要完成的工作性质,接收方需要运行,直到明确告知要停止为止。
有什么建议么?
相关代码:
public class UpdateService extends IntentService {
public UpdateService() {
super(null);
}
@Override
protected void onHandleIntent(Intent intent) {
final int myID = 1234;
Intent notificationintent = new Intent(this, Main.class);
notificationintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, notificationintent, 0);
Notification notice = new Notification(R.drawable.icon_image, "***********", System.currentTimeMillis());
notice.setLatestEventInfo(this, "*************", "***********", pendIntent);
notice.flags |= Notification.FLAG_NO_CLEAR;
startForeground(myID, notice);
boolean screenOn = intent.getBooleanExtra("screen_state", false);
// Blah Blah Blah......
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
IntentServiceonHandleIntent()完成后自动关闭。发生某些事情时,它会执行一些简短的工作。通常,它的寿命不应超过几秒钟。
我将假定这与我在您在该区域的最后一个问题中写的内容有关。
应用程序其余部分将注册和取消注册BroadcastReceiver屏幕开/关事件-显然,从您的评论来看,这是一项活动。如果发生这些事情时您想要做的非常快(几毫秒的量级),只需在onReceive()中完成工作,然后完成它即可。
另一方面,如果您的工作量超过数毫秒,那么您将需要通过其他可以在后台线程上完成工作的工作来完成工作。例如,如果注册了的“应用程序其余部分中的内容” BroadcastReceiver确实是一项活动,则该活动可能只是产生了一项AsyncTask工作。
另一种可能性是使用IntentService。您选择在最后一个问题之前的工作中走这条路。我不知道为什么。无论如何,an IntentService像an一样AsyncTask,应该是短暂的组件-您通过发送命令startService(),它在中执行其工作onHandleIntent(),然后它消失了。
考虑到所有这些,让我们谈谈您的具体观点。
该服务将在一段时间内运行良好,但最终将被终止。
不清楚您认为“杀死”是什么意思。IntentService一旦onHandleIntent()返回,A 自动消失,理想情况下应在几秒钟内发生。
我现在正尝试使用startForeground()来保持该进程运行,但是它似乎仍在消亡。
同样,不清楚您认为“垂死”意味着什么。请记住,IntentService一旦屏幕关闭,仅存在an 并不会阻止CPU关闭,并且startForeground()与此无关。
另外,作为附带说明,由于未调用unregisterReceiver()(除非通过用户手动按下按钮进行手动操作),所以Logcat抱怨存在泄漏。
您还需要在用户退出活动之前注销接收器。调用registerReceiver()in onResume()和unregisterReceiver()in 通常是一个好主意onPause()。
(更新)我认为可能存在以下情况:
1) IntentService状态的文档:
服务会根据需要启动,使用工作线程依次处理每个Intent,并在工作耗尽时自行停止。
因此,可能是您的服务通常在onHandleIntent()完成后停止(特别是,正如您提到的,startForeground()不会增加进程的寿命)。
2)您可能会尝试检查它是否与设备进入休眠状态有关(或者您可能正在按计划启动设备并唤醒设备-在这种情况下,您可能需要获取WakeLock)
3)在极少数情况下,系统仍然可以终止前台进程-因此,如果您进行大量分配(确实很多)和其他一些工作onHandleIntent()(而不是代码中的“ Blah Blah Blah”),则可能会遇到-但我想并非如此。
正如问题的标题是“将startForeground()与IntentService一起使用”一样,我也想澄清一下:我相信没有什么(架构,最佳实践,android框架,IntentService的Java文档)会阻止您将Intent服务作为前台运行。当然,您需要仔细考虑其用法以及您是否确实需要前台服务。这里有一些想法。有关示例代码,请参见下文。(如果您将多个作业/意图排队到IntentService中,则示例代码最终可能会显示多个通知,因此根据您的需要,可能会有更好的解决方案。)
public class ForegroundService extends IntentService {
private static final String TAG = "FrgrndSrv";
public ForegroundService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
Notification.Builder builder = new Notification.Builder(getBaseContext())
.setSmallIcon(R.drawable.ic_foreground_service)
.setTicker("Your Ticker") // use something from something from R.string
.setContentTitle("Your content title") // use something from something from
.setContentText("Your content text") // use something from something from
.setProgress(0, 0, true); // display indeterminate progress
startForeground(1, builder.build());
try {
doIntesiveWork();
} finally {
stopForeground(true);
}
}
protected void doIntesiveWork() {
// Below should be your logic that takes lots of time
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15672 次 |
| 最近记录: |