IntentService的StartForeground

Mat*_*ska 12 android intentservice foreground-service

我有一个IntentService,我希望通过持续通知使其变得粘稠.问题是通知出现然后立即消失.该服务继续运行.我startForeground()IntentService怎么用?

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    Notification notification = new Notification(R.drawable.marker, "Notification service is running",
            System.currentTimeMillis());
    Intent notificationIntent = new Intent(this, DashboardActivity.class);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
        Intent.FLAG_ACTIVITY_SINGLE_TOP);
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
    notification.setLatestEventInfo(this, "App",
            "Notification service is running", pendingIntent);
    notification.flags|=Notification.FLAG_NO_CLEAR;
    startForeground(1337, notification);
    return START_STICKY;
}

@Override
protected void onHandleIntent(Intent intent) {

    String id = intent.getStringExtra(ID);
    WebSocketConnectConfig config = new WebSocketConnectConfig();
    try {
        config.setUrl(new URI("ws://" + App.NET_ADDRESS
                + "/App/socket?id="+id));
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
    ws = SimpleSocketFactory.create(config, this);
    ws.open();
}
Run Code Online (Sandbox Code Playgroud)

谢谢

Com*_*are 22

这不应该是一个IntentService.如上所述,你的IntentService生活将持续一毫秒左右.一旦onHandleIntent()返回,服务就会被销毁.这应该是常规的Service,您可以在其中分叉自己的线程并管理线程和服务的生命周期.

Notification立即离开的原因是因为服务立即消失.

  • Downvoted是因为:这可能是一个错误的答案.摘自IntentService文档:"所有请求都在一个工作线程上处理 - *它们可能需要的时间尽可能长*(并且不会阻止应用程序的主循环),但一次只能处理一个请求." 没有什么说约毫秒左右.https://developer.android.com/reference/android/app/IntentService.html (4认同)
  • 如上所述,这个`IntentService`将存活一毫秒左右,原因很简单,`onHandleIntent()`中的代码只需要一毫秒左右的时间才能运行. (3认同)
  • @GregoryK实际上答案是正确的,因为`onHandleIntent`方法不包含任何线程阻塞代码以防止`IntentService`被破坏。 (2认同)

Gre*_*ryK 6

至于文件IntentService规定:

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

所以,我想问题在于您的服务在onHandleIntent()完成后无法工作。因此,服务会自行停止并取消通知。因此, IntentService 的概念可能不是您任务的最佳案例。


由于问题的标题是“IntentService的StartForeground”,我想澄清一些事情:

让你的 IntentService 在前台运行真的很简单(见下面的代码),但你肯定需要考虑几件事:

  • 如果只需要几秒钟,请不要在前台运行服务 - 这可能会打扰您的用户。想象一下您定期运行短任务 - 这将导致通知出现和消失 - uhhhh*

  • 您可能需要使您的服务能够使设备保持唤醒状态(但那是另一个故事,在 stackoverflow 上有很好的介绍)*

  • 如果您将多个 Intent 排队到您的 IntentService,下面的代码将最终显示/隐藏通知。(因此对于您的情况可能有更好的解决方案 - 正如@CommonsWare 建议扩展 Service 并自己做所有事情,但是想提一下 - IntentService 的 javadoc 中没有任何内容说它只能工作几秒钟 - 只要它必须做点什么。)


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)

  • @CommonsWare 我明白你的意思并理解它。那讲得通。实际上,我有点不同意“如所写的那样,您的 IntentService 将存活一毫秒左右”。我不是要做出假设,API java 说:“IntentService 是按需处理异步请求(表示为 Intent)的服务的基类。客户端通过 startService(Intent) 调用发送请求;服务根据需要启动,使用工作线程依次处理每个 Intent,并在其工作用完时自行停止。” (3认同)