android mvvm livedata_ANDROID架构组件 – ROOM&LIVEDATA - 第1部分【翻译】

a48da1566b4411b65b359d169ac7d3e0.png

以前,Android团队没有提供有关如何构建Android应用程序的建议。在大多数情况下,这意味着任何第一次学习Android的人最终都会将所有代码放入Activity文件中,如果应用程序因NetworkOnMainThreadException崩溃,偶尔会将内容移动到AsyncTask中。只有在尝试添加单元测试和检测测试之后,您才能真正理解您刚刚开发的代码,不易读取,更改或编写测试。

然后每个人都开始讨论不同的模式 - MVP,MVVM,MVI模式,文章和库。 Android框架团队已经意识到强烈需要增加他们为Android应用程序的最佳实践架构提供的指导。 Android团队发布的这些新架构组件旨在改变这一点。

什么是新的架构组件?

架构组件框架是一组库和指南,可作为编写Android应用程序的基础。它们解决了开发人员在各种应用程序中面临的常见情况。该框架旨在减少样板和重复代码的数量,使您专注于应用程序的核心功能。

架构组件的基本块包括以下内容:

  • Room - 一个SQLite对象映射器。与ORMlite或greenDAO等其他库非常相似。它使用SQL,同时仍允许对查询进行编译时保证。
  • LiveData - 生命周期感知的可观察核心组件。
  • ViewModel - 与活动/片段的应用程序的其余部分的通信点。比活动或片段更长久。
  • Lifecycle - 体系结构组件的核心部分,它包含有关组件生命周期状态的信息(例如,活动)。
  • LifecycleOwner - 具有生命周期(活动,碎片,进程,自定义组件)的组件的核心接口。
  • LifecycleObserver - 指定触发某些Lifecycle方法时应发生的情况。创建LifecycleObserver允许组件自包含。

在应用程序中使用新的体系结构组件

我们将构建一个应用程序,它是您添加到应用程序的不同事件的倒计时。我们将使用MVVM模式。

213090cd8ee675250097be024026e81c.gif

下面的图表说明了我们将使用新的Architecture组件构建的Android应用程序。 此图详细说明了我们将在本系列中构建的Date Countdown应用程序的最终结果。 它还指示在应用程序的哪个部分中使用了哪些体系结构组件。

a81ed91c510315ae0e406555b5153b7a.png

MVP和MVVM之间的主要区别在于MVVM ViewModels暴露数据并且感兴趣的各方可以监听该数据(或忽略它),而MVP在View和Presenter之间存在严格的契约。使用MVP,重用Presenters更加困难,因为它们与View紧密耦合。使用MVVM,Views可以从ViewModel订阅他们感兴趣的数据。

什么是Room?

Room是在Android应用中创建数据库的新方法。 Room消除了您之前必须编写的许多样板代码,以便在您的应用中存储数据。 Room是Java类和SQLite之间的ORM。使用Room,您不再需要使用CursorsLoaders。Room不是完全成熟的ORM,例如,您不能像其他ORM解决方案那样提供复杂的对象嵌套。

使用Room,您可以通过几种不同的方式查询数据:

  • 使用LiveData,它是一个公开可以订阅以接收更新的事件流的类。这可以在主线程上使用,因为它是异步的。
  • 使用RxJava2 Flowable抽象类。
  • 将同步调用放在后台线程中,例如AsyncTask。(Room不允许您在主线程上发出数据库查询(因为这会产生ANR))。

开始使用Room

在这个例子中,我们将创建一个允许我们保存重要日期的应用程序,它将显示每个日期的倒计时。。

1.在Android Studio中使用默认的空活动创建新项目。

2.将Google Maven存储库添加到顶级build.gradle:

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

3. 将Room依赖项添加到app / build.gradle:

   compile "android.arch.lifecycle:extensions:1.1.0"
   compile "android.arch.persistence.room:runtime:1.1.0"
   annotationProcessor "android.arch.lifecycle:compiler:1.1.0"
   annotationProcessor "android.arch.persistence.room:compiler:1.1.0-alpha1"

4. 创建一个名为Event的实体。 这个表将存储用户在应用中创建的倒计时事件列表。 我们使用@Entity注释和表的名称(在这种情况下为事件)注释该类。 使用@PrimaryKey注释注释id字段,并选择autoGenerate我们可以在这种情况下设置为true的字段。 然后,Room将使用对象中定义的字段自动创建表格

@Entity(tableName = TABLE_NAME)
public class Event {
   public static final String TABLE_NAME = "events";
   public static final String DATE_FIELD = "date";
 
   @PrimaryKey(autoGenerate = true)
   private int id;
   private String name;
   private String description;
   @ColumnInfo(name = DATE_FIELD)
   private LocalDateTime date;
 
   public Event(int id, String name, String description, LocalDateTime date) {
       this.id = id;
       this.name = name;
       this.description = description;
       this.date = date;
   }
 
   public int getId() {
       return id;
   }
 
   public String getName() {
       return name;
   }
 
   public String getDescription() {
       return description;
   }
 
   public LocalDateTime getDate() {
       return date;
   }
 
   @Override
   public String toString() {
       return "Event{" +
               "id=" + id +
               ", name='" + name + ''' +
               ", description='" + description + ''' +
               ", date=" + date +
               '}';
   }
 
   public long getDaysUntil() {
       return ChronoUnit.DAYS.between(LocalDateTime.now(), getDate());
   }
}

5. 通过创建名为EventDao的接口来创建数据访问对象(或DAO)。 使用@Dao注释注释类。 然后Room将生成一个类实现,它实现接口中定义的方法(非常类似于Retrofit的工作方式)。 我们可以在这里使用不同的注释,注释如@ Query,@ Delete,@ Insert,@ Update。 @Query注释可以采用SQL结构化查询。 关于这一点的重要部分是在这些脚本上发生的编译时间检查。 例如:如果您错误地键入了表格,则在您更正此选项之前,Room不允许您编译应用程序。

@Dao
public interface EventDao {
 
   @Query("SELECT * FROM " + Event.TABLE_NAME + " WHERE " + Event.DATE_FIELD + " > :minDate")
   LiveData<List<Event>> getEvents(LocalDateTime minDate);
 
   @Insert(onConflict = REPLACE)
   void addEvent(Event event);
 
   @Delete
   void deleteEvent(Event event);
 
   @Update(onConflict = REPLACE)
   void updateEvent(Event event);
 
}

6. 创建一个名为EventDatabase的抽象类,这将是连接实体(或表)的地方。该类应继承RoomDatabase。

@Database(entities = {Event.class}, version = 1)
@TypeConverters(DateTypeConverter.class)
public abstract class EventDatabase extends RoomDatabase {
 
   public abstract EventDao eventDao();
 
}

您将注意到返回我们刚刚创建的EventDao的抽象方法eventDao()。 Room在运行时返回此类的实例。

值得注意的是,@ TypeConverters(DateTypeConverter.class)注释会自动将LocalDateTime对象日期序列化为其String格式,并在从存储中读取时将其反序列化为LocalDateTime对象。 下面是DateTypeConverter类的示例类定义:

public class DateTypeConverter {
 
    @TypeConverter
    public static LocalDateTime toDate(Long timestamp) {
       //.. convert
    }
 
    @TypeConverter
    public static Long toTimestamp(LocalDateTime date) {
      //.. convert
    }
}

7.使用Room.databaseBuilder(...)创建单例EventDatabase对象。我们还可以使用Room.inMemoryDatabaseBuilder(..)方法创建内存数据库。我们可以使用Dagger轻松完成此操作或手动创建单例。使用Dagger,我们的模块如下所示

@Module
public class CountdownModule {
 
   private CountdownApplication countdownApplication;
 
   public CountdownModule(CountdownApplication countdownApplication) {
       this.countdownApplication = countdownApplication;
   }
 
   @Provides
   Context applicationContext() {
       return countdownApplication;
   }
 
   @Provides
   @Singleton
   EventRepository providesEventRepository(EventDatabase eventDatabase) {
       return new EventRepositoryImpl(eventDatabase);
   }
 
   @Provides
   @Singleton
   EventDatabase providesEventDatabase(Context context) {
       return Room.databaseBuilder(context.getApplicationContext(), EventDatabase.class, "event_db").build();
   }
}

现在我们有了添加项目,查询和删除的结构,我们可以使用它们并讨论我们在上面定义的EventDao类中使用的LiveData类。

什么是LiveData?

LiveData允许您观察应用程序的多个组件之间的数据更改,而无需在它们之间创建明确且严格的依赖关系路径。 LiveData将遵守活动和片段的不同生命周期。将LiveData与Room结合使用时,它使您能够接收自动数据库更新,这些更新很难通过使用标准SQLiteDatabase来实现

  1. 1创建一个名为EventListActivity的活动和一个名为EventListFragment的片段。 在活动内部,inflate片段。 确保您的片段扩展Fragment(支持库版本)。
  2. 在片段中,添加一个RecyclerView,EventAdapter和EventViewHolder,它们将用于显示我们的事件列表。
  3. 在片段中,我们可以轻松获取对EventDatabase的引用,并在添加新项目时观察数据库中的事件。 在可观察的回调中,我们可以在适配器上设置项目。 我们可以使用Dagger注入EventDatabase对象。
eventDao = eventDatabase.eventDao();
 
eventDao.getEvents().observe(this, events -> {
     Log.d(TAG, "Events Changed:" + events);
     adapter.setItems(events);
});

通过将this作为第一个参数传递,将自动为您管理LiveData observable。这意味着当片段不再使用时,片段将负责处理可观察量。 LiveData类是LifecycleObserver的一个示例。当Lifecycle处于Lifecycle.State.DESTROYED状态时,它会自动停止发送更新,并在Lifecycle处于Lifecycle.State.STARTED状态时重新启动发送更新。

使用Room添加新事件

  1. 1创建一个包含两个EditText字段,日期选择器和保存按钮的新片段。
  2. 保存按钮的onClickListener只需调用eventDatabase.eventDao()。addEvent()即可轻松写入事件数据库。(注意:这应该从后台线程调用,在本例中我使用了RxJava Completable,但如果你愿意,可以使用AsyncTasks)。
String eventTitle = editTextTitle.getText().toString();
String eventDescription = editTextDescription.getText().toString();
Event event = new Event(0, eventTitle, eventDescription, eventDateTime);
 
eventDatabase.eventDao().addEvent(event); //Run this in a background thread.

我们现在可以访问数据库,我们可以从UI轻松插入或查询数据库。

综上所述

Room是一个易于使用的库,它包含Android上的SQLite实现。 它还提供了一个直观的界面来处理Objects而不是Cursors或ContentProviders。 使用带有LiveData的房间是真正的魔法发生的地方。 它允许通知视图有关数据更改的信息,这可能很难通过标准SQLiteDatabase实现。

在活动或片段中直接加载数据有一些缺陷。 主要问题是您的活动或片段与数据库紧密耦合。 如果您想在其他地方添加测试或重用逻辑,这不是一个好方法。 从View逻辑中分离数据库逻辑是一种更好的方法。 ViewModel架构组件旨在解决此问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android MVVM 架构是一种基于 Model-View-ViewModel(模型-视图-视图模型)设计模式的架构,它旨在实现 Android 应用程序的高内聚、低耦合、可测试性和可维护性。在 MVVM 架构中,View(视图)和 ViewModel(视图模型)之间通过数据绑定进行通信,ViewModel(视图模型)和 Model(模型)之间通过业务逻辑进行通信。 MVVM 架构将应用程序分为三个部分: 1. Model:处理数据和业务逻辑,与数据库、网络、API 等打交道。 2. View:负责显示 UI、处理用户输入和事件,是用户与应用程序交互的界面。 3. ViewModel:作为 View 和 Model 之间的桥梁,处理视图逻辑、业务逻辑和数据绑定,将 Model 中的数据转换为 View 可以显示的数据。 在 MVVM 架构中,View 和 ViewModel 之间通过数据绑定实现双向通信,View 可以观察 ViewModel 中的数据变化,并及时更新 UI,同时用户的操作也会触发 ViewModel 中的业务逻辑,从而实现 View 和 Model 的解耦。 MVVM 架构的优点包括: 1. 高内聚、低耦合:各个模块之间的职责清晰明确,代码结构清晰,易于维护。 2. 可测试性:ViewModel 和 Model 都是纯 Java 类,不依赖 Android 系统,易于编写单元测试。 3. 可维护性:MVVM 架构使得代码易于维护和扩展,添加新功能时可以只修改 ViewModel 或 Model,而不影响 View。 总之,MVVM 架构是一种适用于 Android 应用程序的高效、可维护的架构,可以提高开发效率、代码质量和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值