Kotlin realizes the simple use of Service

1 asynchronous communication method

During the running of Android, all programs are executed in the main thread, so when using the thread code block to update some components, an asynchronous communication Handler is required.

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

        //实现异步通信的方式进行更新数据
        val handler=object : Handler(Looper.getMainLooper()){
    
    
            override fun handleMessage(msg: Message) {
    
    
                when(msg.what){
    
    
                    1->textView.text="师者所以传道授业解惑也"
                }
            }
        }
        //如果想在子线程里面进行组件的更新,需要使用到异步机制
        change_textView.setOnClickListener(){
    
    
            thread {
    
    
                val msg=Message()
                //更新文字
                msg.what=1
                handler.sendMessage(msg)
            }
        }
 }

Steps to use: 1 Create a handler object, and rewrite the handlerMessage method in it to process the logic after the message arrives. 2 Create a Message object, and bind the category of the sent message, so that it can distinguish the processing methods of different logics. 3handler to send messages

2Service start and stop

1 Inherit Service in MyService, and implement the methods to obtain a custom Service, mainly including the following methods of onBinder

//此方法用来和Activity进行通信使用
    override fun onBind(intent: Intent): IBinder {
    
    
        return mBinder
    }

    //只有第一次调用的时候才会执行
    override fun onCreate() {
    
    
        super.onCreate()
    }
    //每次启动时都会调用
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    
    
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
    
    
        super.onDestroy()
    }

When starting in Activity, it is similar to the way of starting Activity

start_service.setOnClickListener(){
    
    
            val intent= Intent(this,MyService::class.java)
            startService(intent)
        }
        end_service.setOnClickListener(){
    
    
            val intent=Intent(this,MyService::class.java)
            stopService(intent)
        }

3 Hope that Activity and Service communicate, let Activity know what Service is doing or how it is progressing. You need to use the onBind() method in Service.

1 Inherit the Binder() class in the service, write the logic in this class, and return the result through the onBind() method


class MyService : Service() {
    
    
    //为了实现和Activity的通信,模拟开启服务来进行下载功能
    private val mBinder=DownloadBinder()
    class DownloadBinder: Binder(){
    
    
        fun startDownload(){
    
    
            Log.d("MyService","开始下载")

        }
        fun getProgress():Int{
    
    
            Log.d("MyService","当前下载的进度")
            return 20
        }
    }

    //此方法用来和Activity进行通信使用
    override fun onBind(intent: Intent): IBinder {
    
    
        return mBinder
    }

    //只有第一次调用的时候才会执行
    override fun onCreate() {
    
    
        super.onCreate()
    }
    //每次启动时都会调用
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    
    
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
    
    
        super.onDestroy()
    }

}

2. In the Activity, you need to bind the Activity and the Service first, first implement the method in the ServiceConnection interface, and then perform the logical operation after binding and the logical operation after unbinding in the method.

class ServiceTest:AppCompatActivity() {
    
    

    lateinit var downBinder:MyService.DownloadBinder

    private val connnection=object :ServiceConnection{
    
    
        //该方法会在Activity与Service绑定之后进行调用
        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
    
    
            downBinder=service as MyService.DownloadBinder
            downBinder.startDownload()
            downBinder.getProgress()
        }

        override fun onServiceDisconnected(name: ComponentName?) {
    
    
            Log.d("serviceTest","Service和Activity解绑成功")
        }

    }

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

        //实现异步通信的方式进行更新数据
        val handler=object : Handler(Looper.getMainLooper()){
    
    
            override fun handleMessage(msg: Message) {
    
    
                when(msg.what){
    
    
                    1->textView.text="师者所以传道授业解惑也"
                }
            }
        }
        //如果想在子线程里面进行组件的更新,需要使用到异步机制
        change_textView.setOnClickListener(){
    
    
            thread {
    
    
                val msg=Message()
                //更新文字
                msg.what=1
                handler.sendMessage(msg)
            }
        }
        //service的启动和停止
        start_service.setOnClickListener(){
    
    
            val intent= Intent(this,MyService::class.java)
            startService(intent)
        }
        end_service.setOnClickListener(){
    
    
            val intent=Intent(this,MyService::class.java)
            stopService(intent)
        }
        //数据和Service进行通信,获取到service的正在做的事情,需要对Service进行绑定
        bind_service.setOnClickListener(){
    
    
            val intent=Intent(this,MyService::class.java)
            bindService(intent,connnection, Context.BIND_AUTO_CREATE)//绑定service

        }
        unBind_service.setOnClickListener(){
    
    
            unbindService(connnection)
        }

    }

4 Realize the Service in the foreground

Click the button in the main Activity to start the current Service on the foreground notification


class ForegroundServiceTest : Service() {
    
    
    @RequiresApi(Build.VERSION_CODES.O)
    override fun onCreate() {
    
    
        super.onCreate()
        val manager=getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val channel=NotificationChannel("myService","前台Service通知",NotificationManager.IMPORTANCE_DEFAULT)
        manager.createNotificationChannel(channel)
        val intent=Intent(this,ServiceTest::class.java)
        val pi=PendingIntent.getActivity(this,0,intent,0)
        val notification=NotificationCompat.Builder(this,"myService")
            .setContentTitle("前台Service主题")
            .setContentText("前台的Service的内容")
            .setSmallIcon(R.drawable.ic_baseline_arrow_back_ios_24)
            .setLargeIcon(BitmapFactory.decodeResource(resources,R.drawable.ic_baseline_menu_24))
            .setContentIntent(pi)
            .build()
        startForeground(1,notification)
    }

    override fun onBind(intent: Intent): IBinder {
    
    
        TODO("Return the communication channel to the service.")
    }
}

5 More standardized operations when performing tasks in Service

Generally, time-consuming operations may need to be performed in the Service, and the main thread needs to obtain the results, but ANR (Application Not Responding) will occur after a long time without obtaining the results, so in order to solve this situation, it is more standard The writing method is to create a new thread in the Service to process the task and perform asynchronous work.

 //每次启动时都会调用
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    
    
    thread{
    
    
//在里面进行逻辑的处理工作,最后别忘了进行关闭
         stopSelf()
}
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
    
    
        super.onDestroy()
    }

Guess you like

Origin blog.csdn.net/m0_56184347/article/details/129698143