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