Android官方架构组件介绍之LifeCycle

简介:

下面是官方提供的Android App开发的架构图:

google官方Android架构图

从上图可以看到一些关键字:ViewModel,LiveData,Room等。其实看了上面视频的会发现Google官方Android架构组件一共包括以下几个:

  • LifeCycle : 与Activity和Fragment的生命周期有关

  • LiveData :异步可订阅数据,也是生命周期感知

  • ViewModel :视图数据持有模型,也是生命周期感知

  • Room :SQLite抽象层,用于简化SQLite数据存储

这篇文章主要讲解LifeCycle在项目的简单用法。

AS中添加依赖

首先在工程根目录的build.gradle中添加一下内容:

allprojects {
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }  //添加此行
    }
}

然后在应用目录下的build.gradle中添加以下依赖:

//For Lifecycles, LiveData, and ViewModelcompile "android.arch.lifecycle:runtime:1.0.0-alpha1"compile "android.arch.lifecycle:extensions:1.0.0-alpha1"annotationProcessor "android.arch.lifecycle:compiler:1.0.0-alpha1"//For Roomcompile "android.arch.persistence.room:runtime:1.0.0-alpha1"annotationProcessor "android.arch.persistence.room:compiler:1.0.0-alpha1"

LifeCycle相关使用

在我们平时的项目中经常会遇到很多需要依赖生命周期的逻辑处理,比如有这么一个需求。
在某个Activity我们需要在屏幕上展现用户的地理位置。简单的实现方法如下:

class MyLocationListener {    public MyLocationListener(Context context, Callback callback) {        // ...
    }    void start() {        // connect to system location service
    }    void stop() {        // disconnect from system location service
    }
}class MyActivity extends AppCompatActivity {    private MyLocationListener myLocationListener;    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, (location) -> {            // update UI
        });
  }    public void onStart() {        super.onStart();
        myLocationListener.start();
    }    public void onStop() {        super.onStop();
        myLocationListener.stop();
    }
}

虽然以上代码看起来很简洁,但在实际项目中的onStart,onStop方法可能会变得相当庞大。
此外,实际情况可能并不像上面这么简单,例如我们需要在start位置监听前做用户状态检测,检测是一个耗时的任务,那么很有可能在检测结束前用户提前退出了Activity,这时候就会导致myLocationListener.start()myLocationListener.stop()后面调用,从而引起很多难以定位的问题。代码如下:

class MyActivity extends AppCompatActivity {    private MyLocationListener myLocationListener;    public void onCreate(...) {
        myLocationListener = new MyLocationListener(this, location -> {            // update UI
        });
    }    public void onStart() {        super.onStart();
        Util.checkUserStatus(result -> {            // what if this callback is invoked AFTER activity is stopped?
            if (result) {
                myLocationListener.start();
            }
        });
    }    public void onStop() {        super.onStop();
        myLocationListener.stop();
    }
}

这时候就该今天的主角LifeCycle出场了。它提供了一套接口帮助你处理这些问题。

LifeCycle

LifeCyle类持有Activity或者Fragment的生命周期相关信息,并且支持其他对象监听这些状态。

LifeCyle有两个枚举用于追踪生命周期中的状态。

Event

这是生命周期的事件类,会在Framework和LifeCycle间传递,这些事件映射到Activity和Fragment的回调事件中。

State

LifeCycle所持有Activity或Fragment的当前状态。

一个类想要监听LifeCycle的状态,只需要给其方法加上注解:

public class MyObserver implements LifecycleObserver {    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)    public void onResume() {
    }    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)    public void onPause() {
    }
}
aLifecycleOwner.getLifecycle().addObserver(new MyObserver());

LifeCycleOwner

LifeCycleOwner是一个只有一个方法的接口用于表明其有一个LifeCycle对象。这个方法为getLifecycle()
这个对象给Acitivity,Fragment和LifeCycle提供了一个很好的抽象关系,Activity和Fragment只要实现这个接口就能配合LifeCycle实现生命周期监听。

注意:由于目前LifeCycle处于alpha阶段,所以Fragment和AppCompatActivity并不会实现这些方法,在此之前,可以使用LifecycleActivityLifecycleFragment。等LifeCycle趋于稳定后,Fragment和AppCompatActivity会默认实现这些。

对于之前的位置监听的例子,我们可以让MyLocationListener继承LifecycleObserver,在onCreate中使用LifeCycle进行初始化,剩下的问题则不必担心了。因为MyLocationListener有能力进行生命周期的判断。

class MyActivity extends LifecycleActivity {    private MyLocationListener myLocationListener;    public void onCreate(...) {        //此处进行初始化getLifecycle()传入LifeCycle对象
        myLocationListener = new MyLocationListener(this, getLifecycle(), location -> {            // update UI
        });        //检测用户状态并启用监听
        Util.checkUserStatus(result -> {            if (result) {
                myLocationListener.enable();
            }
        });
  }
}

下面看一下MyLocationListener

class MyLocationListener implements LifecycleObserver {    private boolean enabled = false;    public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) {
       ...
    }    @OnLifecycleEvent(Lifecycle.Event.ON_START)    void start() {        if (enabled) {           // connect
        }
    }    public void enable() {
        enabled = true;        //
        if (lifecycle.getState().isAtLeast(STARTED)) {            // connect if not connected
        }
    }    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)    void stop() {        // disconnect if connected
    }
}

LifeCycle最重要的特性就是在处,他可以提供主动查询生命周期状态的方法。这样就避免了上面遇到的myLocationListener.start()myLocationListener.stop()后面调用的问题。

通过以上的实现,我们的LocationListener是完全的生命周期感知了,它可以进行自己的初始化和资源清理而不必受Activity或者Fragment的管理。这时候如果我们在其他Activity或者Fragment中使用LocationListener,我们只需要初始化它就行了,不必再担心生命周期对它的影响,因为它内部会做好这一切。

通过LefeCycle工作的类我们称之为生命周期感知。鼓励需要使用Android生命周期的类的库提供生命周期感知组件,以便客户端可以轻松地在客户端上集成这些类,而无需手动生命周期管理。

LiveData就是生命周期感知组件的示例,将LiveData和ViewModel一起使用,可以在遵循Android生命周期的情况下,更容易的使用数据来填充UI。

生命周期的最佳实践

  • 保持你的UI(Activity和Fragment)尽可能简洁。它们不应该试图获取它们的数据而是使用ViewModel来执行此操作,并通过LiveData的回调将数据更新到UI中。

  • 尝试编写数据驱动的UI,你的UI的责任是在数据更改时更新视图,或将用户操作通知给ViewModel。

  • 将你的数据逻辑放在ViewModel类中。 ViewModel应该作为UI和其他数据操作的连接器。值得注意的是,ViewModel并不负责提取数据(例如,从网络)。相反,ViewModel应该调用其他接口来执行此工作,然后将结果提供给UI。

  • 使用Data Binding可以让你的的UI代码变得相当干净利落。这将使你的UI更具声明性,并最大限度地减少书写UI更新的代码。如果您更喜欢在Java中执行此操作,请使用像Butter Knife这样的库来避免使用样板代码并进行更好的抽象。

  • 如果你有一个复杂的UI,请考虑创建一个Presenter类来处理UI修改。这通常是过度架构的,但可能有助于使你的UI更容易测试。

  • 不要在ViewModel中引用View或Activity上下文。如果ViewModel在Activity或View销毁的情况下依旧存活,这时将导致内存泄漏。

补充

在自定义的Activity或Fragment中实现LifeCycleOwner,可以实现LifecycleRegistryOwner这个接口。而不是继承(LifeCycleFragment和LifeCycleActivity)

public class MyFragment extends Fragment implements LifecycleRegistryOwner {
    LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);    @Override
    public LifecycleRegistry getLifecycle() {        return lifecycleRegistry;
    }
}

如果你要在自定义的类中实现LifeCycleOwner,可以使用LifecycleRegistry,但是你需要主动向其转发生命周期的事件。但如果你自定义类是Fragment和Activity的话并且它们实现的是LifecycleRegistryOwner,那么事件转发都是自动完成的。


原文地址:h t tp:// w w w .cn bl ogs.com/z qlxtt /p/6887938.html

本文转自帅气的头头博客51CTO博客,原文链接http://blog.51cto.com/12902932/1928046如需转载请自行联系原作者


sshpp

相关文章
|
缓存 Android开发
Android Jetpack系列之Lifecycle
Android Jetpack系列之Lifecycle
847 0
Android Jetpack系列之Lifecycle
|
21天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
23天前
|
缓存 前端开发 Android开发
安卓开发中的自定义视图:从零到英雄
【10月更文挑战第42天】 在安卓的世界里,自定义视图是一块画布,让开发者能够绘制出独一无二的界面体验。本文将带你走进自定义视图的大门,通过深入浅出的方式,让你从零基础到能够独立设计并实现复杂的自定义组件。我们将探索自定义视图的核心概念、实现步骤,以及如何优化你的视图以提高性能和兼容性。准备好了吗?让我们开始这段创造性的旅程吧!
22 1
|
26天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
8天前
|
搜索推荐 前端开发 API
探索安卓开发中的自定义视图:打造个性化用户界面
在安卓应用开发的广阔天地中,自定义视图是一块神奇的画布,让开发者能够突破标准控件的限制,绘制出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战技巧,逐步揭示如何在安卓平台上创建和运用自定义视图来提升用户体验。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开新的视野,让你的应用在众多同质化产品中脱颖而出。
35 19
|
21天前
|
IDE Java 开发工具
移动应用与系统:探索Android开发之旅
在这篇文章中,我们将深入探讨Android开发的各个方面,从基础知识到高级技术。我们将通过代码示例和案例分析,帮助读者更好地理解和掌握Android开发。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和技巧。让我们一起开启Android开发的旅程吧!
|
8天前
|
JSON Java API
探索安卓开发:打造你的首个天气应用
在这篇技术指南中,我们将一起潜入安卓开发的海洋,学习如何从零开始构建一个简单的天气应用。通过这个实践项目,你将掌握安卓开发的核心概念、界面设计、网络编程以及数据解析等技能。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供一个清晰的路线图和实用的代码示例,帮助你在安卓开发的道路上迈出坚实的一步。让我们一起开始这段旅程,打造属于你自己的第一个安卓应用吧!
32 14
|
11天前
|
Java Linux 数据库
探索安卓开发:打造你的第一款应用
在数字时代的浪潮中,每个人都有机会成为创意的实现者。本文将带你走进安卓开发的奇妙世界,通过浅显易懂的语言和实际代码示例,引导你从零开始构建自己的第一款安卓应用。无论你是编程新手还是希望拓展技术的开发者,这篇文章都将为你打开一扇门,让你的创意和技术一起飞扬。
|
9天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
在数字时代,掌握安卓应用开发技能是进入IT行业的关键。本文将引导读者从零基础开始,逐步深入安卓开发的世界,通过实际案例和代码示例,展示如何构建自己的第一个安卓应用。我们将探讨基本概念、开发工具设置、用户界面设计、数据处理以及发布应用的全过程。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你提供宝贵的知识和技能,帮助你在安卓开发的道路上迈出坚实的步伐。
20 5
|
8天前
|
开发框架 Android开发 iOS开发
安卓与iOS开发中的跨平台策略:一次编码,多平台部署
在移动应用开发的广阔天地中,安卓和iOS两大阵营各占一方。随着技术的发展,跨平台开发框架应运而生,它们承诺着“一次编码,到处运行”的便捷。本文将深入探讨跨平台开发的现状、挑战以及未来趋势,同时通过代码示例揭示跨平台工具的实际运用。