2017年,Google发布了Android Architecture Components,包括Room、LiveData、ViewModel和Paging等组件,旨在帮助开发者更轻松地实现MVVM架构。
2018年,Google在I/O大会上推出的一套Android开发组件库,旨在帮助开发者更轻松、更高效地构建Android应用。
随着时间的推移,Android Jetpack不断地更新和增加新的组件,使得Android应用的开发更加高效、稳定和可维护。
今天的主题主要分为三个维度。第一个维度是4W2H分析Jetpack,第二个维度是Jetpack四件套。第三个维度是总结与展望。
其中,4W2H分析Jetpack主要针对Jetpack提出了6个高价值问题。
其中,Jetpack四件套列举了LifeCycle、LiveData、ViewModel和DataBing四种常见的Jetpack工具包。
一、什么场景下使用Jetpack?
Jetpack适用于开发各种类型的Android应用程序,包括单页面应用程序、多页面应用程序、后台任务应用程序等。下面是一些适合使用Jetpack的场景:
- 构建大型应用程序:Jetpack提供了一些库,如ViewModel、LiveData和Navigation,可以帮助开发者更好地管理应用程序的生命周期、状态和导航,使得构建大型应用程序更加容易。
- 处理后台任务:Jetpack中的WorkManager库提供了一种简单、可靠的方式来管理后台任务,如数据同步、推送通知、文件上传等。
- 数据库访问:Jetpack中的Room库提供了一个抽象层,可以让开发者方便地访问和管理SQLite数据库,使得数据存储和访问更加容易。
- 响应式编程:Jetpack中的LiveData和Data Binding库提供了响应式编程的功能,可以让数据在数据源发生变化时自动更新UI,提高应用程序的性能和可靠性。
- 代码重用:Jetpack中的各种库都旨在解决Android应用程序开发中的常见问题,并提供一致的API和开发体验,使得代码重用更加容易。
二、为什么使用Jetpack?
以下是使用Jetpack的一些好处:
- 更好的代码组织和可维护性:Jetpack提供了一组库,这些库旨在解决Android应用程序开发中的常见问题,如生命周期管理、数据存储、后台任务处理等。使用Jetpack可以使代码更加模块化,易于维护。
- 更好的代码可读性:Jetpack提供了一致的API和开发体验,可以使代码更加易于理解和阅读。
- 更好的开发效率:Jetpack提供了一些库和工具,如Navigation和Data Binding,可以帮助开发者更快地开发Android应用程序,提高开发效率。
- 更好的性能和可靠性:Jetpack中的一些库,如LiveData和WorkManager,提供了响应式编程和后台任务处理的功能,可以提高应用程序的性能和可靠性。
- 更好的向后兼容性:Jetpack中的一些库,如ViewModel和LiveData,提供了对Android不同版本的向后兼容性支持,可以使开发者更容易地编写适用于不同版本的Android系统的应用程序。 综上所述,Jetpack可以帮助开发者更好地组织代码、提高开发效率、提高应用程序的性能和可靠性,并提供了对不同版本的Android系统的向后兼容性支持。
三、什么样的团队该使用Jetpack?
Jetpack适用于各种规模的Android开发团队,特别是那些希望提高应用程序质量、开发效率和可维护性的团队。以下是一些团队适合使用Jetpack的场景:
- 大型团队:Jetpack提供了一致的API和开发体验,可以使大型团队更容易协作开发,提高团队的开发效率和代码质量。
- 跨职能团队:Jetpack提供了一些库和工具,如Navigation和Data Binding,可以帮助开发者更快地开发Android应用程序,使得跨职能团队之间更容易协作。
- 需要提高应用程序性能和可靠性的团队:Jetpack中的一些库,如LiveData和WorkManager,提供了响应式编程和后台任务处理的功能,可以提高应用程序的性能和可靠性。
- 需要提高代码可维护性的团队:Jetpack提供了一些库,如ViewModel和Room,可以帮助开发者更好地管理应用程序的状态和数据,使得代码更易于维护。
- 需要保持向后兼容性的团队:Jetpack中的一些库,如ViewModel和LiveData,提供了对Android不同版本的向后兼容性支持,可以使开发者更容易地编写适用于不同版本的Android系统的应用程序。 综上所述,Jetpack适合各种规模和类型的Android开发团队,特别是那些希望提高应用程序质量、开发效率和可维护性的团队。
四、怎样使用Jetpack?
以下是使用Jetpack的一般步骤:
- 添加Jetpack库:Jetpack库可以通过在build.gradle文件中添加依赖项的方式进行添加。例如,添加Lifecycle库的依赖项:
dependencies {
def lifecycle_version = "2.3.1"// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"// Lifecycle
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
}
使用Jetpack库:在添加Jetpack库后,就可以在应用程序中使用Jetpack库提供的功能了。例如,使用ViewModel库创建一个ViewModel类:
import androidx.lifecycle.ViewModel
class MyViewModel : ViewModel() {
// Add ViewModel logic here
}
结合Jetpack组件使用:Jetpack库提供的组件可以结合使用,以提高应用程序的开发效率和可维护性。例如,使用ViewModel库和LiveData库实现一个响应式的用户界面:
class MyActivity : AppCompatActivity() {
private lateinit var viewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my)
// Get a reference to the ViewModel
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
// Observe a LiveData object in the ViewModel
viewModel.someData.observe(this, Observer {
// Update the UI with the new data
})
}
}
以上是使用Jetpack的一般步骤。需要根据具体的Jetpack库和应用程序需求进行相应的配置和代码实现。
五、 使用Jetpack业务价值
使用Jetpack可以带来以下业务价值:
- 提高开发效率:Jetpack提供了一些开发工具和库,例如ViewModel、LiveData和Room,可以减少重复的编写代码,简化开发流程,并提高开发效率。
- 提高应用程序质量:Jetpack提供了一致的API和开发体验,可以减少由于人为因素引起的代码错误,提高应用程序的质量。
- 提高应用程序性能:Jetpack中的一些库,例如Lifecycle和WorkManager,提供了响应式编程和后台任务处理的功能,可以提高应用程序的性能和响应速度。
- 简化应用程序架构:Jetpack提供了一些组件和库,例如ViewModel和Data Binding,可以帮助开发者更好地管理应用程序的状态和数据,并简化应用程序的架构。
- 支持向后兼容性:Jetpack中的一些库,例如ViewModel和LiveData,提供了对Android不同版本的向后兼容性支持,可以使开发者更容易地编写适用于不同版本的Android系统的应用程序。
综上所述,使用Jetpack可以带来多种业务价值,可以提高应用程序的质量、性能和开发效率,同时简化应用程序架构和支持向后兼容性,可以使应用程序更易于维护和升级。
六、Jetpack四件套
6.1 LifeCycle
6.1.1 LifeCycle基础定义
Android Jetpack Lifecycle是Android Jetpack组件库中的一部分,Lifecycle是基于Android Framework中的Lifecycle概念而构建的。
Lifecycle提供了一种轻松管理组件(如Activity和Fragment)生命周期的方式,同时也支持自定义组件的生命周期。
Jetpack Lifecycle提供了一组类和接口,使得开发者可以在组件的生命周期各个阶段执行相应的操作。
这些类和接口包括:
-
LifecycleOwner: 拥有生命周期的对象,通常是Activity和Fragment。
-
LifecycleObserver: 监听组件的生命周期事件的观察者对象。
-
Lifecycle: 组件的生命周期,包括CREATED、STARTED、RESUMED、PAUSED、STOPPED、DESTROYED等状态。
-
LiveData: 一个可观察的数据容器,可以在组件生命周期的不同阶段更新数据。
使用Jetpack Lifecycle,可以更容易地避免内存泄漏和其他生命周期相关的问题。
例如,可以在组件被销毁时自动释放资源、取消网络请求等操作。
此外,Jetpack Lifecycle还提供了一种方式来创建自定义的生命周期状态,以更好地满足App的需求。
总之,Jetpack Lifecycle是Android Jetpack组件库中的一个重要组件,可以帮助开发者更轻松地管理组件的生命周期,从而提高App的质量和性能。
6.1.2 LifeCycle基础使用
在App的主Activity中实现一个简单的计时器,当Activity处于前台时,计时器会不断递增,当Activity被销毁时,计时器将停止。
具体实现步骤如下:
- 在gradle文件中添加Jetpack组件库的依赖。
dependencies {
implementation "androidx.lifecycle:lifecycle-extensions:2.4.0"
}
- 创建一个名为Timer的Java类,并实现LifeCycleObserver接口。
public class Timer implements LifecycleObserver {
private Handler handler;
private int seconds = 0;
@OnLifecycleEvent(Lifecycle.Event.ON_START)public void startTimer() {
handler = new Handler();
handler.post(new Runnable() {
@Overridepublic void run() {
Log.d("Timer", "Seconds: " + seconds);
seconds++;
handler.postDelayed(this, 1000);
}
});
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)public void stopTimer() {
handler.removeCallbacksAndMessages(null);
handler = null;
}
}
- 在MainActivity中添加LifecycleOwner,并在onCreate方法中添加Observer。
public class MainActivity extends AppCompatActivity {
@Overrideprotected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取LifecycleOwner对象LifecycleOwner lifecycleOwner = this;
// 将Timer实例添加为Observer
getLifecycle().addObserver(new Timer());
// ...
}
// ...
}
这样,当Activity处于前台时,Timer实例中的startTimer方法会被调用,计时器会开始递增;
当Activity被销毁时,Timer实例中的stopTimer方法会被调用,计时器会停止。
这个例子展示了如何使用Jetpack LifeCycle组件来管理App组件的生命周期。
当App中存在需要在组件生命周期不同阶段执行的操作时,使用LifeCycle可以更方便地实现这些操作,同时避免了一些常见的生命周期问题
6.1.3 LifeCycle优势劣势
优势
- 管理生命周期方便
- 使用LifeCycle组件可以更方便地管理App组件的生命周期,避免了一些常见的生命周期问题,如内存泄漏和空指针异常等。
- 模块化编程
- 使用LifeCycle组件可以将App的业务逻辑分解为模块化的组件,每个组件负责管理自己的生命周期,便于代码复用和维护。
- 规范化编程
- 使用LifeCycle组件可以规范化App的开发,使代码更易于阅读、理解和维护。
- 支持多个组件
- LifeCycle组件支持多个组件进行生命周期管理,可以轻松地在多个组件之间共享状态和数据。
劣势
- 需要继承LifecycleObserver:在实现LifeCycle功能的时候,需要继承LifecycleObserver接口,这会导致代码的继承关系稍微有点复杂。
- 需要添加注释:在使用LifeCycle组件的时候,需要添加一些注释来指示方法是在什么时候被调用,否则可能会出现一些难以诊断的问题。
6.1.4 LifeCycle应用场景
Jetpack LifeCycle组件的实际开发应用场景包括:
- Activity和Fragment生命周期管理:使用LifeCycle组件可以更方便地管理Activity和Fragment的生命周期,避免了一些常见的生命周期问题,如内存泄漏和空指针异常等。
- 后台服务管理:使用LifeCycle组件可以更方便地管理后台服务的生命周期,可以在App退出后自动停止后台服务,避免了一些不必要的资源浪费。
- 数据库连接管理:使用LifeCycle组件可以更方便地管理数据库连接的生命周期,可以在App退出时自动关闭数据库连接,避免了一些不必要的资源浪费。
- 网络请求管理:使用LifeCycle组件可以更方便地管理网络请求的生命周期,可以在Activity或Fragment销毁时自动取消网络请求,避免了一些不必要的网络请求。
- 视图控制器管理:使用LifeCycle组件可以更方便地管理视图控制器的生命周期,可以在Activity或Fragment销毁时自动清除视图控制器的状态,避免了一些不必要的状态保存和恢复操作。
6.1.5 LifeCycle原理分析
类图
LifecycleOwner表示拥有生命周期的组件,比如Activity和Fragment。
Lifecycle表示组件的生命周期,LifecycleObserver表示一个组件的生命周期观察者。
LifecycleRegistry是Lifecycle接口的一个实现类,它维护了一个生命周期状态机,用于记录组件的生命周期状态和生命周期事件。
LifecycleRegistry提供了一系列方法,用于管理组件的生命周期状态和生命周期事件。当组件的生命周期事件发生变化时,LifecycleRegistry会自动更新状态机,并通知所有的LifecycleObserver观察者对象,以便它们可以相应地更新自己的状态。
LifecycleOwner可以通过getLifecycle()方法获取到一个Lifecycle对象,然后将自己的生命周期观察者对象添加到Lifecycle对象中,从而实现对组件生命周期的监听。
当组件的生命周期事件发生变化时,Lifecycle会自动通知所有的生命周期观察者对象,以便它们可以相应地更新自己的状态。
源码
Lifecycle库的核心是Lifecycle接口和LifecycleObserver接口。
Lifecycle接口定义了一组方法,用于将LifecycleOwner与LifecycleObserver进行关联。
public abstract class Lifecycle {
//添加观察者
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);
//移除观察者
@MainThread
public abstract void removeObserver(@NonNull LifecycleObserver observer);
//获取当前状态
public abstract State getCurrentState();
//生命周期事件,对应Activity生命周期方法
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY //可以响应任意一个事件
}
//生命周期状态. (Event是进入这种状态的事件)
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
//判断至少是某一状态
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
LifecycleObserver接口定义了一组回调方法,用于接收LifecycleOwner的生命周期事件。
在Lifecycle库的实现中,Lifecycle接口有两个重要的实现类,分别是LifecycleRegistry和LifecycleOwner。
LifecycleRegistry实现了Lifecycle接口,并提供了一组方法,用于管理LifecycleOwner的生命周期状态。
LifecycleOwner是一个接口,用于标识拥有生命周期状态的对象,通常是Activity或Fragment。
//androidx.activity.ComponentActivity,这里忽略了一些其他代码,我们只看Lifecycle相关
public class ComponentActivity extends androidx.core.app.ComponentActivity implements LifecycleOwner{
...
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
...
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
ReportFragment.injectIfNeededIn(this); //使用ReportFragment分发生命周期事件
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
@CallSuper
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
Lifecycle lifecycle = getLifecycle();
if (lifecycle instanceof LifecycleRegistry) {
((LifecycleRegistry) lifecycle).setCurrentState(Lifecycle.State.CREATED);
}
super.onSaveInstanceState(outState);
mSavedStateRegistryController.performSave(outState);
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
}
在LifecycleRegistry中,有一个名为mObserverMap的成员变量,用于存储LifecycleObserver对象和其关联的EventObserver对象。
当LifecycleOwner的生命周期状态更改时,LifecycleRegistry会自动调用mObserverMap中与之相关联的EventObserver对象的相应方法,以便它们可以执行适当的操作。
//LifecycleRegistry.java
//系统自定义的保存Observer的map,可在遍历中增删
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap = new FastSafeIterableMap<>();
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);//获取event发生之后的将要处于的状态
moveToState(next);//移动到这个状态
}
private void moveToState(State next) {
if (mState == next) {
return;//如果和当前状态一致,不处理
}
mState = next; //赋值新状态
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
return;
}
mHandlingEvent = true;
sync(); //把生命周期状态同步给所有观察者
mHandlingEvent = false;
}
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
while (!isSynced()) { //isSynced()意思是 所有观察者都同步完了
mNewEventOccurred = false;
//mObserverMap就是 在activity中添加observer后 用于存放observer的map
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
...
static State getStateAfter(Event event) {
switch (event) {
case ON_CREATE:
case ON_STOP:
return CREATED;
case ON_START:
case ON_PAUSE:
return STARTED;
case ON_RESUME:
return RESUMED;
case ON_DESTROY:
return DESTROYED;
case ON_ANY:
break;
}
throw new IllegalArgumentException("Unexpected event value " + event);
}
LifecycleRegistry还提供了一组方法,如handleLifecycleEvent()、getCurrentState()、addObserver()、removeObserver()等,用于管理组件的生命周期状态和LifecycleObserver对象。
在Lifecycle库的实现中,还有一些其他的类和接口,如GenericLifecycleObserver、FullLifecycleObserver、LifecycleEvent、EventObserver等,它们都是用于管理和处理组件生命周期事件的。
6.1.6 LifeCycle注意事项
3.1.6.1 不要在 onCreate() 方法中使用 Lifecycle 组件
Lifecycle 组件在 onCreate() 方法中尚未初始化完成,因此在该方法中使用它们可能会导致崩溃或不可预测的行为。建议在 onStart() 方法中使用 Lifecycle 组件。
3.1.6.2 不要手动调用 onDestroy() 方法
手动调用 onDestroy() 方法会破坏 Lifecycle 组件的生命周期,从而导致应用程序行为异常。Lifecycle 组件应该由系统自动管理,应该避免手动干预。
3.1.6.3 避免在 Fragment 中使用多个 LifecycleOwner
Fragment 自身就是一个 LifecycleOwner,因此不应该在 Fragment 中创建其他的 LifecycleOwner。这样会导致多个 LifecycleOwner 之间的状态不同步,从而导致应用程序出现问题。
篇幅原因没有展示完整
可以 点击 “此处” 即可 免费获取 学习资料 以及 更多Android学习笔记+源码解析+面试视频
技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面
Android 架构师之路还很漫长,与君共勉