将startForeground()与Intent服务一起使用

时间:2012-01-22 19:38:33

标签: android

我正在努力保持对屏幕开/关更改做出反应的服务。该服务可以完美地工作一段时间,但最终它会被杀死。我现在正试图使用​​startForeground()来保持进程活着,但它似乎仍在死亡。我知道没有办法让一个进程永远保持活着,没有错误,但我觉得我必须做错了,因为添加startForeground()不会给进程增加额外的生命。另外,作为附注,Logcat抱怨泄漏,因为没有调用unregisterReceiver()(除非用户按下按钮手动)..但是,由于我想要完成的性质,接收器需要运行直到明确告知停止。

有什么建议吗?

相关守则:

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;
        }

}

3 个答案:

答案 0 :(得分:4)

IntentService完成后,

onHandleIntent()会自动关闭。当事情发生时,它会执行一些简短的工作。它通常不应该存在超过几秒钟。

我将假设这与我写的in your last question in this area有关。


您应用程序其余部分的内容将是注册和取消注册屏幕开/关事件的BroadcastReceiver - 显然,从您的评论中,它是一项活动。如果你想要做的事情发生的时间非常快(大约几毫秒),只需在onReceive()中完成工作,并完成它。

另一方面,如果你有更多的工作而不是几毫秒的价值,你需要通过其他可以在后台线程上完成工作的工作完成这项工作。例如,如果注册BroadcastReceiver的“应用程序其余部分”中的某些内容确实是一项活动,则该活动可能只会生成一个AsyncTask来完成工作。

另一种可能性是使用IntentService。在最后一个问题之前,你选择在你的工作中走这条路。我不知道为什么。无论如何,IntentService,如AsyncTask,应该是一个短命的组件 - 您通过startService()发送命令,它在onHandleIntent()中工作,它就消失了。

考虑到所有这些,让我们谈谈你的具体观点。


  

该服务可以完美地工作一段时间,但最终它会被杀死。

目前还不清楚你认为“被杀”是什么意思。一旦IntentService返回,onHandleIntent()会自动消失,理想情况下应该会在几秒钟内完成。

  

我现在正在尝试使用startForeground()来保持进程活着,但它似乎仍在消亡。

同样,目前还不清楚你认为“死亡”的含义。请记住,仅仅存在IntentService并不会阻止CPU在屏幕关闭时关闭,startForeground()与此无关。

  

另外,作为附注,Logcat抱怨泄漏,因为没有调用unregisterReceiver()(除非用户按下按钮手动)..

您还需要在用户退出活动之前取消注册接收器。通常最好拨打registerReceiver()中的onResume()unregisterReceiver()中的onPause()

答案 1 :(得分:4)

(更新)我想有以下可能的情况:

对于IntentService状态,

1) documentation

  

根据需要启动服务,使用a依次处理每个Intent   工作线程,并在失去工作时自行停止。

因此,可能是您的服务通常在onHandleIntent()完成后停止(特别是,正如您提到的那样,startForeground()没有为流程添加额外的生命。)

2)您可能会尝试检查它是否与设备进入睡眠有关(或者您可能是按计划启动服务并唤醒设备 - 在这种情况下,您可能需要获得WakeLock

3)在极少数情况下,系统仍然可以杀死前台进程 - 所以如果你在onHandleIntent()进行了大量的分配(真的很多)和其他一些工作(相反" Blah Blah Blah"在你的代码中 - 你可能遇到它 - 但我认为情况并非如此。

问题的标题是"将startForeground()用于IntentService" - 也想澄清一下: 我相信没有(架构,最佳实践,Android框架,IntentService的java文档)阻止您将意图服务作为前台运行。当然,您需要仔细考虑其用法以及是否确实需要前台服务。有些想法可供here。有关示例代码,请参阅下文(如果您将多个作业/意图排入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();
        }
    }
}

答案 2 :(得分:0)

如果内存不足而你消耗的内存太多而你在后台呆的时间太长,那么你将被ActivityManager杀死。