简介:Service Android四大组件之一,可以在后台长时间运行,没有UI界面,默认是运行在主线程.
如需耗时操作需要开启线程,也可以用Service的子类IntentService默认是运行在子线程,其实内部是HandlerThread+Handler,不过Android8.0以后就弃用.也可以用JobIntentService,不过好像现在也弃用了,反正目前官网是这么写的…
1.启动方式
2种显示启动方式startService() 或者bindService().
为什么不隐式启动?
因为Android5.0开始,Google要求必须使用显示启动Service.
1.1startService()启动方式
//启动服务
val intent = Intent(applicationContext, FloatingWindowService::class.java)
startService(intent)
//停止服务
stopService(Intent(applicationContext, FloatingWindowService::class.java))
生命周期
onCreate() ,第一次被创建,被系统调用.
↓↓
onStartCommand() ,startService方法启动Service时,被调用.
↓↓
onDestroy() ,stopService方法启动Service时,被调用.
1.2bindService()启动方式
//启动服务
bindService(intent,conn,Context.BIND_AUTO_CREATE)
//解绑服务
unbindService(conn)
//监控服务状态 ,IBinder对象可以调用服务内部的方法
var conn = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
floatingBind = service as FloatingWindowService.FloatingBind
val service1 = floatingBind.service
Log.i(TAG, "onServiceConnected: service 已绑定")
}
override fun onServiceDisconnected(name: ComponentName?) {
Log.i(TAG, "onServiceDisconnected:$name ")
}
}
生命周期
onCreate() ,第一次被创建时被系统调用.
↓↓
onBind() ,bindService方法启动Service时,被调用.
↓↓
onUnbind() ,unbindService方法解除绑定时,被调用.
↓↓
onDestroy() ,unbindService方法解除绑定时,被调用.
2.Service与Activity通信方式
这边Activity主要是用IBinder调用Service内部方法,给Service发送信息.
Service通过接口回调方式返回数据给Activity.
在这里插入代码片
2.1 Activity给Service发送信息
//Activity
var conn = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
floatingBind = service as FloatingWindowService.FloatingBind
val service1 = floatingBind.service
//给service发送数据
floatingBind.setData("activity返回数据${count}")
Log.i(TAG, "onServiceConnected: service 已绑定 设置数据callBack")
}
override fun onServiceDisconnected(name: ComponentName?) {
Log.i(TAG, "onServiceDisconnected:$name ")
}
}
//Service
var data = "null"
fun upData(msg: String) {
data = msg
Log.i(TAG, "upData: 收到activity 数据$data")
}
inner class FloatingBind : Binder() {
val service: FloatingWindowService get() = this@FloatingWindowService
fun setData(data: String) {
this@FloatingWindowService.upData(data)
}
}
2.2 Service给Activity回调信息
//Service
...
if (this@FloatingWindowService::dataCallBack.isInitialized) {
//回调数据给activity
dataCallBack.message(jobIndex)
}
...
interface DataCallBack {
fun message(count: Int)
}
private lateinit var dataCallBack: DataCallBack
fun setCallBack(dataCallBacks: DataCallBack) {
dataCallBack = dataCallBacks
}
//Activity
bindService(intent, conn, Context.BIND_AUTO_CREATE)
var conn = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
floatingBind = service as FloatingWindowService.FloatingBind
val service1 = floatingBind.service
Log.i(TAG, "onServiceConnected: service 已绑定 设置数据callBack")
service1.setCallBack(object : FloatingWindowService.DataCallBack {
override fun message(count: Int) {
Log.i(TAG, "message: service 回调数据$count")
}
})
}
override fun onServiceDisconnected(name: ComponentName?) {
Log.i(TAG, "onServiceDisconnected:$name ")
}
}
完整代码
Activity
class FloatingAct : AppCompatActivity() {
var TAG = "FloatingAct"
lateinit var mBinding: ActivityFloatingBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = ActivityFloatingBinding.inflate(layoutInflater)
setContentView(mBinding.root)
initView()
}
private fun initView() {
mBinding.bt1.setOnClickListener {
val intent = Intent(applicationContext, FloatingWindowService::class.java)
//intent.putExtra("activity",handler)
//start方式
//startService(intent)
//bind方式
bindService(intent, conn, Context.BIND_AUTO_CREATE)
}
mBinding.bt2.setOnClickListener {
if (this::floatingBind.isInitialized) {
//解绑service
unbindService(conn)
Log.i(TAG, "initView:unbindService ")
}
//stopService(Intent(applicationContext, FloatingWindowService::class.java))
}
mBinding.bt3.setOnClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
startActivity(
Intent(
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:$packageName")
)
)
} else {
Toast.makeText(
applicationContext,
"API < " + Build.VERSION_CODES.M,
Toast.LENGTH_SHORT
).show()
}
}
}
lateinit var floatingBind: FloatingWindowService.FloatingBind
var conn = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
floatingBind = service as FloatingWindowService.FloatingBind
val service1 = floatingBind.service
Log.i(TAG, "onServiceConnected: service 已绑定 设置数据callBack")
service1.setCallBack(object : FloatingWindowService.DataCallBack {
override fun message(count: Int) {
Log.i(TAG, "message: service 回调数据$count")
if (this@FloatingAct::floatingBind.isInitialized) {
floatingBind.setData("activity返回数据${count}")
}
}
})
}
override fun onServiceDisconnected(name: ComponentName?) {
Log.i(TAG, "onServiceDisconnected:$name ")
}
}
}
Service
class FloatingWindowService : Service() {
companion object {
val TAG = "FloatingWindowService"
}
lateinit var floatView: View
override fun onBind(intent: Intent?): IBinder? {
if (!this::floatView.isInitialized) {
initView()
}
Log.i(TAG, "onBind: ")
return FloatingBind()
}
override fun onCreate() {
super.onCreate()
Log.i(TAG, "onCreate: 创建service")
}
//每次startServcie时都会调用该方法
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (!this::floatView.isInitialized) {
initView()
}
Log.i(TAG, "onStartCommand - startId: $startId")
return super.onStartCommand(intent, flags, startId)
}
//解绑调用
override fun onUnbind(intent: Intent?): Boolean {
Log.i(TAG, "onUnbind: ")
return super.onUnbind(intent)
}
private fun initView() {
var jobIndex = 0
timer = Timer()
timer.schedule(object : TimerTask() {
override fun run() {
jobIndex++
//Log.i(TAG, "run: 执行定时任务${jobIndex}")
info.text = "补货动态刷新中:${jobIndex}\n 补货数量:$data"
if (this@FloatingWindowService::dataCallBack.isInitialized) {
dataCallBack.message(jobIndex)
}
}
}, 0, 2000)
Log.i(TAG, "initView: 初始化悬浮窗 width:$widthPixels height:$heightPixels")
}
private fun stopTimer() {
timer.cancel()
}
//退出销毁
override fun onDestroy() {
super.onDestroy()
Log.i(TAG, "onDestroy: ")
}
var data = "null"
fun upData(msg: String) {
data = msg
Log.i(TAG, "upData: 收到activity 数据$data")
}
inner class FloatingBind : Binder() {
val service: FloatingWindowService get() = this@FloatingWindowService
fun setData(data: String) {
this@FloatingWindowService.upData(data)
}
}
interface DataCallBack {
fun message(count: Int)
}
private lateinit var dataCallBack: DataCallBack
fun setCallBack(dataCallBacks: DataCallBack) {
dataCallBack = dataCallBacks
}
}