Android核心主题1------服务1(Android Service:前台服务、后台服务、绑定服务)

1.什么是Service:

  1. Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件。服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行。

  2. 此外,组件可通过绑定到服务与之进行交互,甚至是执行进程间通信 (IPC)。例如,服务可在后台处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序进行交互。

2. 服务分为三种不同的类型:

  1. 前台服务

前台服务执行一些用户能注意到的操作。例如,音频应用会使用前台服务来播放音频曲目。前台服务必须显示通知。即使用户停止与应用的交互,前台服务仍会继续运行。

首先,Service类中使用startForeground方法来设置前台服务并显示通知。

kotlin 复制代码
import android.app.Notification
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.media.MediaPlayer
import android.os.IBinder
import androidx.core.app.NotificationCompat

class AudioPlayerService : Service() {

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        startForegroundService()
        return START_NOT_STICKY
    }

    // 当服务启动时调用此方法。
    private fun startForegroundService() {
        // 创建一个意图以在通知被点击时启动MainActivity。
        val notificationIntent = Intent(this, MainActivity::class.java)
        // 创建一个PendingIntent来包装notificationIntent。
        val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0)

        // 使用NotificationCompat.Builder构建通知。
        val notification = NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("音频播放器") // 设置通知的标题。
            .setContentText("正在播放音频") // 设置通知的文本内容。
            .setSmallIcon(R.drawable.ic_notification) // 设置通知的小图标。
            .setContentIntent(pendingIntent) // 设置通知的PendingIntent。
            .build()

        // 使用给定的通知启动前台服务。
        startForeground(NOTIFICATION_ID, notification)
    }

    // 当服务被销毁时调用此方法。
    override fun onDestroy() {
        super.onDestroy()
        // 停止服务在前台运行。
        stopForeground(true)
    }

    // 当客户端绑定到服务时调用此方法。
    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    companion object {
        private const val CHANNEL_ID = "audio_channel" // 通知渠道的ID。
        private const val NOTIFICATION_ID = 1 // 通知的ID。
    }
}

接下来,在Activity中启动Service。

kotlin 复制代码
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val intent = Intent(this, AudioPlayerService::class.java)
		startService(intent)
    }
}

注意:WorkManager API提供了一种灵活的任务调度方式,在许多情况下,可以使用WorkManager,这比直接使用前台服务更可取。

  1. 后台服务

后台服务执行用户不会直接注意到的操作。例如,如果应用使用某个服务来压缩其存储空间,则此服务通常是后台服务。

示例代码:

kotlin 复制代码
import android.app.Service
import android.content.Intent
import android.os.IBinder

class CompressionService : Service() {

    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
        // 在这里执行压缩存储空间的操作
        compressStorage()

        // 压缩完成后,停止服务
        stopSelf()

        return START_NOT_STICKY
    }

    private fun compressStorage() {
        // 执行压缩存储空间的操作
    }
}

要在应用中启动此后台服务,可以在适当的位置(例如,活动或广播接收器)中使用以下代码:

kotlin 复制代码
val intent = Intent(context, CompressionService::class.java)
context.startService(intent)

这将触发CompressionService的onStartCommand方法,在其中执行压缩存储空间的操作。执行完操作后,服务将调用stopSelf()方法停止自身。

注意:如果您的应用面向 API 级别 26 或更高版本,当应用本身未在前台运行时,系统会对运行后台服务施加限制。在诸如此类的大多数情况下,您的应用应改为使用WorkManager

  1. 绑定服务

当应用组件通过调用 bindService() 绑定到服务时,服务即处于绑定状态。绑定服务会提供客户端-服务器接口,以便组件与服务进行交互、发送请求、接收结果,甚至是利用进程间通信 (IPC) 跨进程执行这些操作。仅当与另一个应用组件绑定时,绑定服务才会运行。多个组件可同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。

一个常见的例子是音乐播放器应用程序。以下是一个简化的示例,展示了如何使用绑定服务在应用程序中播放和控制音乐。

首先,创建一个Service类,名为MusicPlayerService,用于处理音乐播放的逻辑。

kotlin 复制代码
import android.app.Service
import android.content.Intent
import android.media.MediaPlayer
import android.os.Binder
import android.os.IBinder

class MusicPlayerService : Service() {
    private val binder = MusicPlayerBinder()
    private var mediaPlayer: MediaPlayer? = null

    inner class MusicPlayerBinder : Binder() {
        fun getService(): MusicPlayerService = this@MusicPlayerService
    }

    override fun onBind(intent: Intent): IBinder {
        return binder
    }

    fun playMusic() {
        // 在这里实现播放音乐的逻辑
        mediaPlayer = MediaPlayer.create(this, R.raw.my_music)
        mediaPlayer?.start()
    }

    fun pauseMusic() {
        // 在这里实现暂停音乐的逻辑
        mediaPlayer?.pause()
    }

    fun stopMusic() {
        // 在这里实现停止音乐的逻辑
        mediaPlayer?.stop()
        mediaPlayer?.release()
        mediaPlayer = null
    }
}

接下来,在你的Activity中,你可以使用ServiceConnection来绑定服务并与之交互。以下是一个示例Activity的代码:

kotlin 复制代码
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle
import android.os.IBinder
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private var isServiceBound = false
    private var musicPlayerService: MusicPlayerService? = null

    private val connection = object : ServiceConnection {
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            val binder = service as MusicPlayerService.MusicPlayerBinder
            musicPlayerService = binder.getService()
            isServiceBound = true
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            isServiceBound = false
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val playButton = findViewById<Button>(R.id.play_button)
        val pauseButton = findViewById<Button>(R.id.pause_button)
        val stopButton = findViewById<Button>(R.id.stop_button)

        playButton.setOnClickListener {
            if (isServiceBound) {
                musicPlayerService?.playMusic()
            }
        }

        pauseButton.setOnClickListener {
            if (isServiceBound) {
                musicPlayerService?.pauseMusic()
            }
        }

        stopButton.setOnClickListener {
            if (isServiceBound) {
                musicPlayerService?.stopMusic()
            }
        }
    }

    override fun onStart() {
        super.onStart()
        val intent = Intent(this, MusicPlayerService::class.java)
        bindService(intent, connection, Context.BIND_AUTO_CREATE)
    }

    override fun onStop() {
        super.onStop()
        if (isServiceBound) {
            unbindService(connection)
            isServiceBound = false
        }
    }
}

在这个示例中,我们在Activity的onStart方法中使用bindService方法来绑定MusicPlayerService服务,并在onStop方法中使用unbindService方法来解绑服务。

Thank you for your reading, best regards!

相关推荐
Kapaseker15 小时前
你不看会后悔的2025年终总结
android·kotlin
alexhilton18 小时前
务实的模块化:连接模块(wiring modules)的妙用
android·kotlin·android jetpack
ji_shuke19 小时前
opencv-mobile 和 ncnn-android 环境配置
android·前端·javascript·人工智能·opencv
sunnyday042621 小时前
Spring Boot 项目中使用 Dynamic Datasource 实现多数据源管理
android·spring boot·后端
幽络源小助理1 天前
下载安装AndroidStudio配置Gradle运行第一个kotlin程序
android·开发语言·kotlin
inBuilder低代码平台1 天前
浅谈安卓Webview从初级到高级应用
android·java·webview
豌豆学姐1 天前
Sora2 短剧视频创作中如何保持人物一致性?角色创建接口教程
android·java·aigc·php·音视频·uniapp
白熊小北极1 天前
Android Jetpack Compose折叠屏感知与适配
android
HelloBan1 天前
setHintTextColor不生效
android
洞窝技术1 天前
从0到30+:智能家居配网协议融合的实战与思考
android