Jetpack“全家福”
定义:属于android开发组件工具集(只要是能够帮助开发者更好更方便的构建应用程序的组件,Google都将其纳入了Jetpack)
特点:不依赖于任何android系统版本,这些组件大多数定义在androidX库之下,拥有非常好的向下兼容性
目的:帮助我们编写更加简洁的代码,并简化我们的开发过程
以上组件当中我们最需要关心的还是架构组件,架构组件对项目的影响最大也是使我们代码更加健壮的关键,架构组件也是Jetpack的核心组件。
1.ViewModel
Viewmodel是Jetpack最重要的组件之一,因为在传统模式下Activity的任务实在太重了,既负责逻辑处理又要控制UI展示,甚至还要处理网络回调等等,因而使用Viewmodel可以帮助Activity分担一部分工作,它可以专门来存放一切与界面相关的数据
作用:单独保存数据,相应业务模型
使用场景:Activity翻转时使用ViewModel保证数据的时刻保存
生命周期:onCreate->onDestory 长于Activity或Fragment
ViewModel的基本使用
build.gradle添加引用 implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"
自定义一个类实现ViewModel接口并定义需要的数据
class MainViewModel:ViewModel(){
var counter = 0
}
在Activity或Fragment中初始化
之所以这么写是因为ViewModel有独立的生命周期,防止类似于手机翻转后导致对ViewModel的多次初始化
lateinit var viewModel :MainViewModel
(<你的Activity或Fragment实例>) (<你的VIewModel>)
viewModel = ViewModelProviders.of(this).get(MainViewModel::java.class)
viewModel.counter = ...
由于我们MailViewModel的构造函数中没有参数,但我们有时候确实需要构造函数来传递一些参数,但我们ViewModel的构建又是通过 ViewModelProviders获取的所以不能直接传递参数给ViewModel
构造方法传递参数
class MainViewModel:ViewModel(count :Int){
var counter = count
}
class MainViewModelFactory(private val count: Int) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return MainViewModel(count) as T
}
}
初始化
viewModel = ViewModelProviders.of(this, MainViewModelFactory(countReserved)).get(MainViewModel::class.java)
2.Lifecycles
作用:用来感知Activity的生命周期,为了解决手写感知Activity而增加太多额外逻辑的缺点
使用场景:收到网络请求响应时界面可能已经关闭,此时不应该再去处理响应后的逻辑;在非Actvitiy中感应Activity的生命周期
Lifecycles的基本使用
先定义Observer类实现LifecycleObserver空方法(需要自己定义方法)接口,在需要对应生命周期的方法中增加对应注解(如@OnLifecycleEvent(Lifecycle.Event.ON_START))
class MyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun activityStart() {
Log.d("MyObserver", "activityStart")
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun activityStop() {
Log.d("MyObserver", "activityStop")
}
}
在已经继承AppCompatActivity的Activity或继承androidx中的Fragment中可以通过以下方式为Activity增加监听
public class MainActivity extends AppCompatActivity implements LifecycleOwner{ //LifecycleRegistry 实现了Lifecycle private LifecycleRegistry mLifecycleRegistry=new LifecycleRegistry(MainActivity.this); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_next); MyObserver myObserver = new MyObserver(); mLifecycleRegistry.addObserver(myObserver); } @Override public Lifecycle getLifecycle() { return mLifecycleRegistry; } }
通过getLifecycle()方法获取Lifecycle实例,然后通过lifecycle.addObserver(Observer)进行Observer和Activity(或Fragment)的绑定,括号中传入实现LifecycleObserver的类,至此完成绑定,可以在自定义的Observer类中处理相应的逻辑
3.LiveData
定义:是Jetpack提供的一种响应式编程组件,它可以包含任何类型的数据,并在数据发生变化时通知给观察者
作用:在进行对数据的耗时操作后依然保证数据的准确性
使用场景:ViewModel在耗时操作中修改数据,然后监听其数据变化结果
ViewModel使用LiveData进行包装,在Activity中观察,就可以主动将数据变化通知Actvitiy了
class MainViewModel(countReserved: Int) : ViewModel() {
private val _counter = MutableLiveData<Int>()
val counter: LiveData<Int> get() = _counter
init {
_counter.value = countReserved
}
fun plusOne() {
val count = _counter.value ?: 0
_counter.value = count + 1
}
fun clear() {
_counter.value = 0
}
}
以上写法当外部调用counter变量时实际获取的是_counter的实例,但是无法给counter设置数据,从而保证ViewModel的数据封闭性,以上是android官方最为推荐的ViewModel和LiveData结合的定义写法
MutableLiveData是一种可变的LiveData,提供了三种读写方法setValue(),getValue()(主线程),postValue()(非主线程设置数据),任何一个LiveData对象都可以通过observe()方法来观察数据的变化,具体写法如下
viewModel.counter.observe(this){ count->
//TODO具体逻辑
}
4.WorkManager
前提:setvice以前的优先级过高,导致android手机的耗电量急剧增加,官方不得已在每次版本更新后将后台权限一步步收紧
作用:编写后台代码的同时可以保证不同android版本上的兼容性
使用场景:不使用Service完成后台服务
缺点:时间不确定,任务不一定会执行完成
1.定义后台任务实现相应逻辑
class SimpleWorker(context:Context,params:WorkerParameters):Worker(context,params){
override fun doWork():Result{
//do somethings
return Result.success()//返回是否执行成功
}
}
2.配置后台任务的运行条件和约束信息
val request = OneTimeWorkRequest.Builder(SimpleWork::class.java).build//完成单次运行后台任务的构建
val request = PeriodicWorkRequest.Builder(SimpleWork::class.java,15,).build//完成周期性后台任务的构建 不低于15分钟
3.将后台请求传入WorkManager的enqueue()方法中
WorkManager.getInstance(context).enqueue(request)
额外功能:设置标签 链式任务
由于大多数手机厂商会给手机提供一件清理的功能,所以导致WorkManager很容易被杀死,WorkManager可以用但不建议实现核心功能