Android 启动service(Kotlin)

一、使用startForegroundService()或startService()启用service

**Activity

复制代码
 //启动service
val intent: Intent = Intent(ServiceActivity@this,MyService::class.java)
//Build.VERSION_CODES.O = 26
// Android8以后,不允许后台启动Service
if(Build.VERSION.SDK_INT >= 26){
    startForegroundService(intent)
 }else{
    startService(intent)
 }

**Service

复制代码
package com.example.buju.service


import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat

class MyService:Service() {

    override fun onCreate() {
        super.onCreate()
        Log.e("MyService","onCreate")

        initNotification()
    }

     // 初始化通知(安卓8.0之后必须实现)
    private fun initNotification() {

        val channelName = "channelName"
        val channelId = "channelId"
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            // 发送通知,把service置于前台
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            // 从Android 8.0开始,需要注册通知通道
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH)
                notificationManager.createNotificationChannel(channel)
            }

            // 页面跳转
            val intent = Intent(applicationContext,ServiceActivity::class.java)
            val pendingIntent = PendingIntent.getActivity(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT)

            // 创建通知并配置相应属性
            val notification = NotificationCompat.Builder(this, channelId)
                .setSmallIcon(android.R.drawable.star_off)//小图标一定需要设置,否则会报错(如果不设置它启动服务前台化不会报错,但是你会发现这个通知不会启动),如果是普通通知,不设置必然报错
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), android.R.drawable.star_on))
                .setContentTitle("通知标题")// 标题
                .setContentText("通知内容")// 内容
                .setPriority(NotificationCompat.PRIORITY_DEFAULT)
                .setContentIntent(pendingIntent)// 设置跳转
                .setWhen(System.currentTimeMillis())
                .setAutoCancel(false)
                .setOngoing(true)
                .build()
            // 注意第一个参数不能为0
            startForeground(1, notification)


        }
    }


    override fun onBind(intent: Intent?): IBinder? {
        Log.e("MyService","onBind")
        return null
    }


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.e("MyService","onStartCommand")
        return super.onStartCommand(intent, flags, startId)

    }

    override fun onUnbind(intent: Intent?): Boolean {
        Log.e("MyService","onUnbind")
        return super.onUnbind(intent)
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.e("MyService","onDestroy")
        //停止的时候销毁前台服务。
        stopForeground(true);

    }

}

注意该方法不会调用onBind()和onUnbind()

二、绑定启用service

**Activity

复制代码
package com.example.buju

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.util.Log
import android.view.View
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import com.example.buju.service.MyService

class ServiceActivity:AppCompatActivity() {
    private var myBinder:MyService.MyBinder? = null
    lateinit var startBtn:Button
    lateinit var stopBtn:Button
    lateinit var getBtn:Button

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

        initControls()

    }

    /**
     * 控件初始化
     * */
    private fun initControls(){

        startBtn = findViewById(R.id.startBtn)
        startBtn.setOnClickListener(btnClick)

        stopBtn = findViewById(R.id.stopBtn)
        stopBtn.setOnClickListener(btnClick)

        getBtn = findViewById(R.id.getBtn)
        getBtn.setOnClickListener(btnClick)

    }

    /**
     * service 连接
     * */
    private val connection = object:ServiceConnection{
        //Activity与Service连接成功时回调该方法
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
            Log.e("MyService","---------Service 成功连接----------")
            myBinder = service as MyService.MyBinder
        }
        // Activity与Service断开连接时回调该方法
        override fun onServiceDisconnected(name: ComponentName?) {
            Log.e("MyService","---------Service 断开连接----------")
        }
    }

    /**
     * 点击事件
     * */
   val btnClick:(View)->Unit = {
       when(it.id) {
           R.id.startBtn -> {
               // 绑定service
               val intent: Intent = Intent(ServiceActivity@this,MyService::class.java)
               bindService(intent,connection,Context.BIND_AUTO_CREATE)


           }
           R.id.stopBtn ->{
               // 解除绑定
               unbindService(connection)
           }
           R.id.getBtn ->{
               // 获取service传递过来的数据
               Log.e("MyService","getCount=${myBinder?.getCount()}")
           }
           else ->{

           }

       }

   }



    override fun finish() {
        super.finish()
        overridePendingTransition(R.anim.slide_no,R.anim.slide_out_from_bottom)
    }

    override fun onDestroy() {
        super.onDestroy()

        // 解除绑定
        unbindService(connection)
    }

}

**Service

复制代码
package com.example.buju.service


import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Binder
import android.os.Build
import android.os.IBinder
import android.util.Log
import androidx.core.app.NotificationCompat

class MyService:Service() {
    /**
     * 用于传递参数
     * */
    private var count:Int = 0

    private var myBinder:MyBinder = MyBinder()

    inner class MyBinder: Binder(){
        fun getCount():Int?{
            return count
        }
    }

    override fun onCreate() {
        super.onCreate()
        Log.e("MyService","onCreate")

        Thread(Runnable {
            Thread.sleep(1000)
            count=100
        }).start()

        initNotification()
    }

    // 初始化通知(安卓8.0之后必须实现)
    private fun initNotification() {
        val channelName = "channelName"
        val channelId = "channelId"
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            // 发送通知,把service置于前台
            val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            // 从Android 8.0开始,需要注册通知通道
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                val channel = NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_HIGH)
                notificationManager.createNotificationChannel(channel)
            }
            val notification = NotificationCompat.Builder(this, channelId)
                .setSmallIcon(android.R.drawable.star_off)//小图标一定需要设置,否则会报错(如果不设置它启动服务前台化不会报错,但是你会发现这个通知不会启动),如果是普通通知,不设置必然报错
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), android.R.drawable.star_on))
                .setContentTitle("通知标题")// 标题
                .setContentText("通知内容")// 内容
                .setWhen(System.currentTimeMillis())
                .setAutoCancel(false)
                .setOngoing(true)
                .build()

            // 注意第一个参数不能为0
            startForeground(1, notification)

        }
    }



    override fun onBind(intent: Intent?): IBinder? {
        Log.e("MyService","onBind")
        return myBinder
    }


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.e("MyService","onStartCommand")
        return super.onStartCommand(intent, flags, startId)

    }

    override fun onUnbind(intent: Intent?): Boolean {
        Log.e("MyService","onUnbind")
        return super.onUnbind(intent)
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.e("MyService","onDestroy")
        //停止的时候销毁前台服务。
        stopForeground(true);

    }

}
相关推荐
liang_jy9 分钟前
Android 事件分发机制(二)—— 点击事件透传
android·面试·源码
圆号本昊3 小时前
Flutter Android Live2D 2026 实战:模型加载 + 集成渲染 + 显示全流程 + 10 个核心坑( OpenGL )
android·flutter·live2d
冬奇Lab4 小时前
ANR实战分析:一次audioserver死锁引发的系统级故障排查
android·性能优化·debug
冬奇Lab4 小时前
Android车机卡顿案例剖析:从Binder耗尽到单例缺失的深度排查
android·性能优化·debug
ZHANG13HAO5 小时前
调用脚本实现 App 自动升级(无需无感、允许进程中断)
android
圆号本昊5 小时前
【2025最新】Flutter 加载显示 Live2D 角色,实战与踩坑全链路分享
android·flutter
小曹要微笑6 小时前
MySQL的TRIM函数
android·数据库·mysql
mrsyf7 小时前
Android Studio Otter 2(2025.2.2版本)安装和Gradle配置
android·ide·android studio
DB虚空行者7 小时前
MySQL恢复之Binlog格式详解
android·数据库·mysql