Android 开发加速器 Jetpack(1)_第1张图片 封面

Jetpack 是一套 Android 解决方案,初衷是让天下没有难开发的 Android 应用。Android 背着小火箭的 logo 并不是表示 Android 使用了 Jetpack 会有多少速度提升,而是加速了 Android 开发的速度。
现在无论是在 web 的 react 还是在 flutter 的 widget 前端的策略都是在走组件化。在 Jetpack 也有四大组件分别用于解决不同方面问题,根据需要可自由组合,没有限制。

基本要求

要安装使用 Jetpack 依赖我们首先应该确保 Android Studio 升级到 3.0 以上版本。能够吸收可能内容还需要具备一些 Android 开发基础知识,例如了解 RecylerView。

简介 Android Architecture Components

其实 Android Architecture Components 设计的目标就是解决在数据发生变化了,及时更新界面的痛点。
在 Android Architecture Components 中不同库来根据不同方面的解决方案。是一套可以搭建出稳定性高、可测试以及易于维护的框架。Android Architecture Components 是 jetpack 一部分,Jetpack 是 Android 软件组件的集合。


Android 开发加速器 Jetpack(1)_第2张图片 jetpack

在 jetpack 中每一个组件都是可以独立使用,并不是相互依存的。开发者可以根据应用开发具体需要自由选择这些特性。

Architecture

  • DataBinding
  • LifecycleAwareComponents
  • LifecycleOwner 和 LifecycleObserver
  • LiveData
  • Navigation
  • Paging
  • Room
  • ViewModel
  • WorkManager

Lifecycle Aware Components

Android 开发加速器 Jetpack(1)_第3张图片 lifecycle-aware

每一个 Android 的 Activity 都有自己生命周期,在 Lifecycle Aware Components 中的 Activity 作为 Lifecycle Owner (也就是 Lifecycle 的所有者)使用。 Lifecycle Owner 带有 Event(事件)和 State(状态) 的类,每一个 Event 都对应着一个状态(例如 onCreate 事件对应 CREATED 状态)。在 Lifecycle Aware Components 还有一个就是 用于执行动作的 LifecycleObserver。是用于定义在不同状态下会执行那些动作。

引入依赖包

    def lifecycle_version = "1.1.1"    implementation "android.arch.lifecycle:extensions:$lifecycle_version"    implementation "android.arch.lifecycle:compiler:$lifecycle_version"

因为 Activity 可以作为 LifecycleOwner 使用那么我们就只需要创建一个 LifecycleObserver。

public class MainActivityObserver implements LifecycleObserver {}

通过 @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) 注解来定义在不同状态下进行动作,LifecycleObserver 会时刻观察 Activity/Fragment(作为 LifecycleOwner)的状态来进行不同动作。这里为了便于观察只是打印出一句话。

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)    public void onCreateEvent(){        Log.d(TAG, "onCreateEvent: ON_CREATE");    }

LifecycleObserver 需要对应于一个 Activity,在作为 LifecycleOwner 的 Activity 中的 onCreate 方法中将刚刚创建好的 LifecycleObserver 与其相关联。

getLifecycle().addObserver(new MainActivityObserver());

如果运行报错,可以尝试在模块的 gradle.build 添加以下代码。

        javaCompileOptions {            annotationProcessorOptions{                includeCompileClasspath true            }        }

从下面输出可以看出他们执行先后属性,不过在不同状态执行顺序会有所不同,这个可以大家自己动手以尝试,我在这里就一一演示了。

I/Main2Activity: onCreate: main2ActivityI/MainActivityObserver: onCreateEvent: ON_CREATE

简单总结一下 LifecycleOwner 在其中作为生产者(提供者)提供状态供作为消费者的 LifecycleObserver 来使用,LifecycleObserver 会观察 LifecycleOwner 一举一动(状态改变)进行相应。
那么这样做好处是什么,代码更加清晰我们不必在 Activity 的生命周期中去写具体回调,而且便于测试。

ViewModel

为什么我们需要 ViewModel
当我们旋转屏幕(也就是 configuration 发生)触发了 RotationEvent 从而让 Activity 会重新初始化,所以之前数据会重新获取而发生变化,多数情况我们希望界面上数据是不变的。

Android 开发加速器 Jetpack(1)_第4张图片Android 开发加速器 Jetpack(1)_第5张图片

在图中,我们可以观察理解到 ViewModel 整个生命周期,ViewModel 最后在应用不再是当前应用时候才会被销毁。提供了 ViewModel 销毁的回调 onCleared
这样可以将数据维护的工作从 Activity 肩膀上拿下里交给 ViewModel 来做,从而减少 Activity 的工作。


Android 开发加速器 Jetpack(1)_第6张图片

ViewModel 负责持有数据,而让 Activity 专注于绘制界面接收用户的操作。建议使用 Repository 负责从网络获取数据或者是在本地存储数据的工作。

Android 开发加速器 Jetpack(1)_第7张图片

创建 MainActivityDataGenerator 模拟数据提供的类,每一次 getNumber 会重新生成一个随机数。

public class MainActivityDataGenerator {    private String TAG = this.getClass().getSimpleName();    private String myRandomNumber;    public String getNumber(){        Log.i(TAG, "Get Number: ");        if(myRandomNumber == null){            createNumber();        }        return myRandomNumber;    }    public void createNumber(){        Log.i(TAG, "createNumber: ");        Random random = new Random();        myRandomNumber = "Number: " + (random.nextInt(10 - 1) + 1);    }}

在 Activity 中引用 MainActivityDataGenerator 的数据,将随机数渲染到界面。

public class Main2Activity extends AppCompatActivity {    private String TAG = this.getClass().getSimpleName();    private TextView textView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        MainActivityDataGenerator generator = new MainActivityDataGenerator();        textView = findViewById(R.id.main2_textView);        textView.setText(generator.getNumber());        Log.i(TAG, "onCreate: main2Activity");    }}

在上面代码基础,我们运行程序就会发现,当我们旋转手机屏幕时候,数值也发生变化了,好接下来我们就开始使用 ViewModel 修复这个问题。

public class MainActivityDataGenerator extends ViewModel

首先让 MainActivityDataGenerator 继承 ViewModel 类,最好 MainActivityDataGenerator 名修改以 ViewModel 结尾这样更加清晰,例如 MainActivityViewModel。这就是我们在 MainActivityDataGenerator 实现所做的工作,是不是很简单。

在 Activity 中

 protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        MainActivityDataGenerator model =                ViewModelProviders.of(this).get(MainActivityDataGenerator.class);        textView = findViewById(R.id.main2_textView);        textView.setText(model.getNumber());        Log.i(TAG, "onCreate: main2Activity");    }
  MainActivityDataGenerator model =                ViewModelProviders.of(this).get(MainActivityDataGenerator.class);

在 ViewModelProviders.of 方法中我们需要传入这个 Activity 然后 get 传入继承了 ViewModel 的类。
然后返回都会 MainActivityDataGenerator 添加一个回调便于观察

    @Override    protected void onCleared() {        super.onCleared();        Log.i(TAG, "ViewModel Destroyed: ");    }

总结一下 ViewModel 会提供一个存活在即使配置发生变化的情况,用于提供 UI 其所需数据。
ViewModel 结合 LiveData 和 DataBiding 可以开发出响应式的应用。


Android 开发加速器 Jetpack(1)_第8张图片

在 ViewModel 不可以持有 context,这样做会造成内存溢出,从下图可以看出,ViewModel 的生命周期包括配置变化,如果 ViewModel 持有了 Activity 的实例,在配置变化了之前 Activity 也不会被销毁从而造成了内存泄漏。

Android 开发加速器 Jetpack(1)_第9张图片

更多相关文章

  1. Android FileProvider应用之间共享数据
  2. 2011年linux数据库的android在线分享
  3. 如何使用Jdbc和Servlet操作Mysql数据库,编写Android登录注册服务
  4. Android与服务器端数据交互(http协议整合struts2+android)
  5. android加载网络图片(逐行扫描格式png图片)的一个bug
  6. [置顶] Android实现数据存储技术集锦
  7. Android 应用程序之间数据共享 - ContentProvider
  8. [转] Android TextView处理HTML标签、显示图片等
  9. 信息浏览器从Android的浏览器中传递cookie数据到App中信息浏览器

随机推荐

  1. MySQL服务器的SSD性能问题分析和测试详解
  2. MySQL5.7.24版本的数据库安装过程图文详
  3. 最新mysql 5.7.23安装配置图文教程
  4. mysql 5.7.24 安装配置方法图文教程
  5. mysql 5.7.24 安装配置图文教程
  6. 88秒插入1000万条数据到MySQL数据库表的
  7. MySQL 5.7并发复制隐式bug实例分析
  8. mysql5.7.23版本安装教程及配置方法
  9. mysql中的锁机制深入讲解
  10. innodb如何巧妙的实现事务隔离级别详解