您现在的位置是:首页 >技术杂谈 >Android Jetpack应用指南--阅读笔记网站首页技术杂谈

Android Jetpack应用指南--阅读笔记

一颗暗色星辰 2024-06-23 06:01:02
简介Android Jetpack应用指南--阅读笔记

一、初始Jetpack

Jetpack是谷歌官方给出的一个统一的Android架构解决方案,它包含四个部分,分别是架构、UI、基础和行为,每个部分都有各自的一些组件,像架构部分就有LiveData、ViewModel、Room、Navigation、Lifecycle、DataBinding、Paging等常用组件

因为Jetpack的组件并入了AndroidX,所以想使用JetPack的话,需要先将项目迁移至AndroidX,可以通过AS菜单栏中的Refactor->Migrate to AndroidX功能选项来进行迁移,迁移前会有一个提示框,显示是否备份原项目,可以选择备份,再进行迁移(Android Support Library在版本28之后就不再更新了)

二、LifeCycle

LifeCycle组件主要是为了解决开发过程中需要感知系统组件生命周期,但又不愿与系统组件过多耦合的问题

添加Lifestyle依赖:

implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"

使用非常简单,对于Activity、Fragment来说,自身就已经实现了LifecycleOwner接口,我们只需要实现一个LifecycleObserver即可,然后在Activity、Fragment的onCreate方法里调用:

lifecycle.addObserver(lifecycleObserver)

在onDestroy里调用:

lifecycle.removeObserver(lifecycleObserver)

即可

Service中稍有不同,需要我们继承LifecycleService,该类提供了获取Service生命周期的方法,其它都与Service一样,然后像Activity和Fragment那样添加移除观察者就好了

如果要监听application的生命周期,监控用户回到前台、后台的时机,可以在自定义的Application的onCreate里调用:

ProcessLifecycleOwner.get().lifecycle.addObserver(MyApplicationLifecycleObserver())

即可,回到前台会调用onStart、onResume,回到后台会调用onPause、onStop,onCreate只会调用一次,onDestroy不会调用

LifestyleObserver可以实现DefaultLifecycleObserver接口,在各个生命周期回调里进行相关处理

三、Navigatioin

DeepLink在Navigation中应用的两种场景,一种是通知,通过PendingIntent构造跳转Navigation指定fragment的Intent,具体代码如下:

Navigation.findNavController(this@MainActivity, R.id.xxx)
     .createDeepLink()
     .setGraph()
     .setDestination() 
     .setArguments()
     .createPendingIntent()

另一种是通过外部浏览器跳转,需要先在导航图里添加<deepLink/>标签:

<fragment
    android:id=""
    ...>
    <!--id、name作为路径参数,phone、time作为查询参数-->   
    <!--路径参数可以为路径的子集,例如scx://example.com/id{id}/{name} 这里的id也是合法的-->        
    <deepLink app:uri="scx://example.com/{id}/{name}?phone={phone}&time={time}"
</fragment>
     
参考:https://blog.csdn.net/stephen_sun_/article/details/123339025

然后在清单文件里为Activity设置<nav-graph/>标签:

<activity android:name="">
  //为Activity设置<nav-graph/>标签
  <nav-graph android:value="@navigation/xxx"/>
</activity>

最后使用adb工具测试:

adb shell am start -a android.intent.action.VIEW -d "http://www.YourWebsite.com/ParamsFromUrl"

四、ViewModel

记录页面的数据,有独立的生命周期,比较简单,只记录一个感兴趣的问题解答博客:

屏幕旋转导致Activity销毁重建,ViewModel是如何恢复数据的 - 掘金 (juejin.cn)

五、LiveData

LiveData是一个可被观察的数据容器类,它将数据包装起来,使数据成为被观察者

LiveData本质上采用的是观察者模式,而且能够感知页面的生命周期,从而只在页面处于onStart和onResume状态时更新数据,如果需要在页面任何状态都能感知数据的变化,可以使用observeForever方法,不过此时一定要记着在不需要时调用removeObserver方法移除监听,避免内存泄漏

六、Room

Room包含三个部分,分别是Entity、Dao、Database,定义了表结构、查询、数据库的相关信息,Room可以与LiveData配合使用,当表数据改变时,LiveData能自动检测到数据库变化并通知到观察者,从而更新UI

参考:如何使用LiveData实现Room数据库的数据变化监听? - 掘金 (juejin.cn)

从Room2.2开始,加入了两个API,分别是createFromAsset()和createFromFile(),createFromAsset表示从asset目录下加载数据库文件并以此文件为基础创建数据库,createFromFile表示从手机存储中加载数据库文件并创建数据库,在创建数据库时可以调用,进行数据库的数据预填充

七、WorkManager

WorkManager旨在帮助开发者在后台处理不需要及时执行的任务,开发者可以设置触发条件、任务执行顺序,剩下的交由WorkManager处理就可以了,WorkManager会在满足触发条件后的某个时刻开始执行任务,WorkManager宣称能够保证任务一定得到执行,无论是杀死app还是重启设备,但是在国内真机上测试结果却不一定,可能是国内系统修改的缘故,所以使用WorkManager时需要考虑这一点

WorkManager使用流程:

1.继承Worker类并重写doWork执行耗时任务,并根据执行结果返回相对应的Result(Result.success()、Result.failure()、Result.retry())

2.构造Constraints类对象设置任务触发条件,并设置给WorkRequest,构造一个任务请求对象,WorkRequest还可以设置tag、延迟执行时间、指数退避策略、给Worker传递参数等

3.将任务提交给系统:

WorkManager.getInstance(this).enqueue(workRequest)

4.通过获取WorkInfo观察任务状态

WorkManager.getInstance(this).getWorkInfosByTag()
或
WorkManager.getInstance(this).getWorkInfosByTagLiveData()

5.取消任务

WorkManager.getInstance(this).cancelAllWork()

八、Databinding

1.启用databind

dataBinding{
    enabled=true
}

2.xml中使用layout做根节点,使用variable作为引入数据,还可以在data中引入静态类,在控件中进行使用

<layout 
    ...
    <data>
        <import type="引入的静态类"/>
        <variable
            name=""
            type=""/>
    </data>
    //使用时用@{variable中name}即可
    ...
</layout>

3.在二级页面绑定

在include标签里,使用app:name=@{variable.name}其中name是二级页面中data里定义的<variable>里定义的变量名

4.自定义BindingAdapter

在类中定义相应的静态方法,添加@BindingAdapter("name")注解,其中name是在xml中使用的属性名字(如app:name=""),确保布局文件最外层包含以下命名空间,这样才能调用那些使用@BindingAdapter注解定义的静态方法,静态方法的第一个参数是控件名字,比如要给ImageView自定义属性,第一个参数就是ImageView imageView,第二个参数或后边多个参数是自定义属性,如下:

//命名空间
xmlns:app="http://***.android.com/apk/res-auto"

//BindingAdapter实例
@BindingAdapter(value={"image","defaultImageResource"},requireAll=false)
public static void setImage(ImageView imageView,String imageUrl,int imageResource){
    if(!TextUtils.isEmpty(imageUrl){
        Glide.with(context).load(imageUrl).into(imageView);
    }else{
        imageView.setImageResource(imageResource);
    }
}
//调用:
<ImageView
    ...
    app:image=""
    app:defaultImageResource=""
    ...
</ImageView>
//如果有多个属性可以用上面那种形式,如果只有一个可以省去value=,直接写属性名即可;requireAll表
//示这些参数是否都要赋值

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。