android项目开发:多线程编程
仍然是《第一行代码》的笔记,不过略过了deprated的内容,并探究了下Handler的工作机制。 上班了,果然没有那么多大块时间写博客了。
仍然是《第一行代码》的笔记,不过略过了deprated的内容,并探究了下Handler的工作机制。
上班了,果然没有那么多大块时间写博客了。
Handler
主线程不能进行耗时处理,子线程不能访问UI,所以我们需要异步消息处理机制。
使用
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
when(msg.what){
MSG_UPDATE_TEXT -> binding.textView.text = "Nice to meet you. "
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initView()
}
private fun initView() {
binding.apply {
changeTextButton.setOnClickListener {
thread {
val msg = Message()
msg.what = MSG_UPDATE_TEXT
handler.sendMessage(msg)
}
}
}
}
companion object {
private const val MSG_UPDATE_TEXT = 1
}
}
原理
图片有点多,懒得一张张转移了,去我整理的文档看吧:
Service
三个回调:
onCreate()在Service创建时调用onStartCommand()在Service每次启动时被调用onDestory()在Service销毁时调用
通过startService(intent)和stopService(intent)的方式启动和停止Service。
Binder用于和View绑定通信。Binder和前台Service具体参见下面例子。
package top.ntutn.servicetest
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
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.util.Log
import androidx.core.app.NotificationCompat
class MyService : Service() {
private val mBinder = DownloadBinder()
class DownloadBinder : Binder() {
fun startDownload() {
Log.d(javaClass.simpleName, "startDownload() executed")
}
fun getProcess(): Int {
Log.d(javaClass.simpleName, "getProcess() executed")
return 0
}
}
override fun onBind(intent: Intent) = mBinder
override fun onCreate() {
super.onCreate()
Log.d(javaClass.simpleName, "onCreate() executed")
val manager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
"my_service",
"前台Service通知",
NotificationManager.IMPORTANCE_DEFAULT
)
manager.createNotificationChannel(channel)
}
val intent = Intent(this, MainActivity::class.java)
val pi = PendingIntent.getActivity(this, REQ_MY_SERVICE, intent, 0)
val notification = NotificationCompat.Builder(this, "my_service")
.setContentTitle("This is content title")
.setContentText("This is content text. ")
.setContentIntent(pi)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setLargeIcon(BitmapFactory.decodeResource(resources,R.drawable.ic_launcher_foreground))
.build()
startForeground(1, notification)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d(javaClass.simpleName, "onStartCommand() executed")
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
Log.d(javaClass.simpleName, "onDestroy() executed")
}
companion object {
private const val REQ_MY_SERVICE = 0
}
}
package top.ntutn.servicetest
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 androidx.appcompat.app.AppCompatActivity
import top.ntutn.servicetest.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var downloadBinder: MyService.DownloadBinder
private val connection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName, service: IBinder) {
downloadBinder = service as MyService.DownloadBinder
downloadBinder.startDownload()
downloadBinder.getProcess()
}
override fun onServiceDisconnected(name: ComponentName?) = Unit
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initView()
}
private fun initView() {
binding.apply {
startServiceButton.setOnClickListener {
val intent = Intent(this@MainActivity, MyService::class.java)
startService(intent)
}
stopServiceButton.setOnClickListener {
val intent = Intent(this@MainActivity, MyService::class.java)
stopService(intent)
}
bindServiceButton.setOnClickListener {
val intent = Intent(this@MainActivity, MyService::class.java)
bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
unbindServiceButton.setOnClickListener {
unbindService(connection)
}
}
}
}
最后修改于 2020-08-21