Android前台服务的澄清

6
我的应用程序目前使用后台服务与物理设备进行通信(蓝牙)。 (我制造和销售物理设备。)该应用程序每500毫秒向设备发送一条命令。用户启动此过程并且它必须一直运行直到用户停止它。在应用程序处于活动状态时,会将该过程的结果发送到应用程序。即使应用程序不活动,该过程也需要运行。(例如,他们接听电话,搜索网络。)一旦应用程序再次变为活动状态,则该过程的状态与应用程序同步。该过程可以运行从几分钟到许多小时。(是的,如果用户想要运行99小时的过程,则需要插入电源。)大多数用户运行时间为2-15分钟。现在一切都很好,但是使用API 26,似乎不再允许这种架构。一种迁移选项是转移到前台服务。但是,我发现文档对前台服务的工作方式不清楚。前台服务是否在应用程序不活动时继续运行?(即已经通过onPause。)如果是这样,这与后台服务有何不同?是否有更好的文档说明前台服务的工作原理。(我的网络搜索没有找到任何重要信息。)此外,API 26文档未说明如果应用程序绑定到后台服务,新限制是否仍然适用。他们吗?
谢谢, 斯坦
2个回答

14
一个前台服务是指您将其置于前台状态的服务,这意味着如果系统需要CPU或者您的应用已关闭,则系统不会杀死该进程。
首先,您有三种类型的服务:
- 启动服务(在UI线程中运行) - IntentService(在自己的线程中运行)(请参见Services vs IntentServices) - 绑定服务(只要有一个活动绑定了它,就会一直运行)
如上所述,如果您关闭应用程序,则绑定服务也将被关闭,它是通过bindService()启动的。 IntentServiceService的子类型,它简化了针对传入意图的"工作队列流程",即它会在队列中逐个处理传入的意图,正如IntentService description中所说。它具有默认实现,并通过startService()启动。它主要用于异步任务。

已启动服务是由组件启动的服务,直到调用stopService()或关闭您的应用程序才会继续存在。

使用前台服务使您的Service 持久化。您必须在服务内部调用startForeground()。它将一直运行,直到您停止Service,例如使用stopSelf()stopService()

注意:每次调用startService()时都会触发onStartCommand(),但只有在第一次创建时才会触发onCreate()

这是一个简单的前台启动服务实现:

在您的Manifest.xml文件中:

<service android:name=".ConnectionService"
    android:enabled="true"/>

在MyService.java文件中:

public class MyService extends Service {
    // Unique notification identifier
    private final static int NOTIFICATION_ID = 95;

    private NotificationManager mNotificationManager;

    public MyService() { super(); }

    @Override
    public void onCreate() {
        // Initialize notification
        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);

        // Build your notification here
        mBuilder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher));
        mBuilder.setSmallIcon(R.mipmap.ic_small_icon);
        mBuilder.setContentTitle("MyService");
        mBuilder.setContentText("The Service is currently running");

        // Launch notification
        startForeground(NOTIFICATION_ID, mBuilder.build());
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // Handle startService() if you need to
        // for exmple if you are passing data in your intent
        return START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // We don't provide binding, so return null
        return null;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // Remove the notification when the service is stopped
        mNotificationManager.cancel(NOTIFICATION_ID);
    }
}

最后只需调用startService()即可。

0

前台服务对我来说是新的,但它看起来像是在状态栏中有一个图标的服务,所以它确实有一个用户界面。你有没有研究过jobinfo?它似乎是在后台运行作业的一种方式。如果你想让你的服务在启动完成后启动这篇文章可能会有所帮助。最后,这可能是一个冒险,但在Android设备上转到设置>应用程序并选择一个已安装的应用程序。你会发现屏幕弹出,因为程序员覆盖了android.accounts.AccountAuthenticator操作。换句话说,系统启动了一个活动,而不是Launcher意图。同样的方式,当蓝牙连接时,系统必须调用一个你可以覆盖的意图,也许是android.bluetooth.device.action.FOUND 看看这个


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接