赞
踩
Jetpack的热度,想必大家有目共睹!现在越来越多的公司招聘要求Jetpack是必会项目,Google也在疯狂的更新Jetpack组件,热度完全不亚于Kotlin!所以说呢?还不卷起来么?
那么Jetpack是什么呢?
如图所示
Jetpack是一个由多个库组成的套件,可帮助开发者遵循最佳做法,减少样板代码并编写可在各种Android版本和设备中一致运行的代码,让开发者精力集中编写重要的代码。
如图所示
简单的说就是用来监听Activity与Fragment的生命周期变化
概念说了一大堆了!该实战了!
布局文件
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <Chronometer android:id="@+id/chronometer" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
这里可以看出,里面定义了一个计时器组件。来看看实现逻辑!
class Step1Activity : AppCompatActivity() { private var chronometer: Chronometer? = null private var elapsedTime: Long = 0L override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) chronometer = findViewById(R.id.chronometer) } override fun onResume() { super.onResume() chronometer!!.base = SystemClock.elapsedRealtime() - elapsedTime chronometer!!.start() } override fun onPause() { super.onPause() elapsedTime = SystemClock.elapsedRealtime() - chronometer!!.base chronometer!!.stop() } }
这简短的逻辑,想必小伙伴们能够一眼就能知道。开始与暂停计时分别在onResume
与onPause
方法。
从未用过Jetpack
的你,感觉这样写好像并没有什么问题!
但是仔细考虑下,这样写是不是将控件与生命周期绑定的太死了?
而且当我们长周期的变量在短周期使用,当短周期结束时,如果没有及时释放还会造成内存泄露!
因此,来看看使用Jetpack将会带来怎样的故事?
@SuppressLint("ViewConstructor") class MyChronometer : Chronometer, LifecycleObserver { constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet) var elapsedTime: Long = 0 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) open fun startMeter() { base = SystemClock.elapsedRealtime() - elapsedTime start() } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) open fun stopMeter() { elapsedTime = SystemClock.elapsedRealtime() - base stop() } }
这时,我们看到:
Chronometer
计时器,实现了LifecycleObserver
接口将自定义控件添加至布局里(这里我就不贴布局代码了吧)
最新的activity:
class Step2Activity : AppCompatActivity() {
private var chronometer: MyChronometer? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
chronometer = findViewById(R.id.chronometer)
lifecycle.addObserver(chronometer!!)
}
}
这里我们看到,使用LifeCycle后,对应控件根本不需要和activity生命周期绑死了,只需要添加一句lifecycle.addObserver(chronometer!!)
就OK了!
现在我们解决了activity的生命周期耦合度(Fragment同理,读者可以尝试),那Service呢?将是怎样呢?
当然Google粑粑肯定为我们考虑好了的,那就是对应的Service
使用LifecycleService
。
看看LifecycleService
源码:
public class LifecycleService extends Service implements LifecycleOwner {
....略
}
看到这句,就确定了LifecycleService
就是Service
,所以可以放心大胆的使用!
这里我就用定位服务举例
MyLocationService.kt
class MyLocationService : LifecycleService {
constructor() {
Log.d("hqk", "MyLocationService")
val observer = MyLocationObserver(this)
lifecycle.addObserver(observer)
}
}
这里并没有在Service
对应生命周期里实现对应的定位服务,而是使用了自定义的MyLocationObserver
,来看看它长啥样?
MyLocationObserver.kt
class MyLocationObserver : LifecycleObserver { private var context: Context? = null private var locationManager: LocationManager? = null private var locationListener: MyLocationListener? = null constructor(context: Context) { this.context = context } @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) private fun startGetLocation() { Log.d("hqk", "startGetLocation") locationManager = context!!.getSystemService(Context.LOCATION_SERVICE) as LocationManager //定位监听 locationListener = MyLocationListener() //权限校验 if (ActivityCompat.checkSelfPermission( context!!, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( context!!, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) { return } //权限通过,开启定位 locationManager?.requestLocationUpdates( LocationManager.GPS_PROVIDER, 3000, 1f, locationListener!! //定位回调监听 ) } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) private fun stopGetLocation() { Log.d("hqk", "stopGetLocation") locationManager!!.removeUpdates(locationListener!!) } internal class MyLocationListener : LocationListener { //定位成功或者位置发生改变时将会回到该方法 override fun onLocationChanged(location: Location) { Log.d("hqk", "location changed:$location") } override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {} override fun onProviderEnabled(provider: String) {} override fun onProviderDisabled(provider: String) {} } }
代码解析
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".Step3Activity"> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="startGps" android:text="开始" android:textSize="30sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.498" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.354" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="stopGps" android:text="停止" android:textSize="30sp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.506" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.632" tools:ignore="OnClick" /> </androidx.constraintlayout.widget.ConstraintLayout>
class Step3Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main_two)
}
fun startGps(view: View) {
startService(Intent(this, MyLocationService::class.java))
}
fun stopGps(view: View) {
stopService(Intent(this, MyLocationService::class.java))
}
}
注意:这里我就没有写什么权限申请了,偷下懒,而是直接去设置里改的权限。
运行效果
点击开始按钮时:
/com.hqk.lifecycle D/hqk: MyLocationService
/com.hqk.lifecycle D/hqk: startGetLocation
/com.hqk.lifecycle D/hqk: location changed:Location[gps 30.705794,104.041993 acc=1 et=+58m34s576ms alt=0.0 vel=0.0 bear=0.0 {Bundle[EMPTY_PARCEL]}]
位置发生改变时:
/com.hqk.lifecycle D/hqk: location changed:Location[gps 30.667559,104.034240 acc=1 et=+59m55s464ms alt=0.0 vel=0.0 bear=0.0 {Bundle[mParcelledData.dataSize=40]}]
点击结束按钮时:
/com.hqk.lifecycle D/hqk: stopGetLocation
这里讲解了对应activity与service,当然也可以监听对应App的生命周期。
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
ProcessLifecycleOwner.get().lifecycle
.addObserver(ApplicationObserver())
}
}
ApplicationObserver.kt
class ApplicationObserver : LifecycleObserver { private val tag = "hqk" @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) fun onCreate() { Log.d(tag, "Lifecycle.Event.ON_CREATE") } @OnLifecycleEvent(Lifecycle.Event.ON_START) fun onStart() { Log.d(tag, "Lifecycle.Event.ON_START") } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun onResume() { Log.d(tag, "Lifecycle.Event.ON_RESUME") } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun onPause() { Log.d(tag, "Lifecycle.Event.ON_PAUSE") } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun onStop() { Log.d(tag, "Lifecycle.Event.ON_STOP") } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun onDestroy() { Log.d(tag, "Lifecycle.Event.ON_DESTROY") } }
运行效果
进入App时
/com.hqk.lifecycle D/hqk: Lifecycle.Event.ON_CREATE
/com.hqk.lifecycle D/hqk: Lifecycle.Event.ON_START
/com.hqk.lifecycle D/hqk: Lifecycle.Event.ON_RESUME
退出后台/结束运行时
/com.hqk.lifecycle D/hqk: Lifecycle.Event.ON_PAUSE
/com.hqk.lifecycle D/hqk: Lifecycle.Event.ON_STOP
这里的ProcessLifecycleOwner.get().lifecycle
Lifecycle.Event.ON_CREATE
只会调用一次。Lifecycle.Event.ON_DESTROY
永远不会被调用,Google粑粑不可能让开发者在这搞事情通过这几个实战我们能够发现:
好了,本篇到这里差不多结束了,相信你对Jetpack对应的LifeCycle有了一定的认知,在下一篇中,将会讲解Jetpack里面的ViewModel与LiveData。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。