阅读 1705

[译] App架构指南之开山篇

本文译自Android开发者文档中Android Architecture Components视频介绍 科学上网观看完整视频 转载请注明出处

应开发者需求,Android Framework 团队撰写了一份Android应用构建指南,还开发出了配套的构建组件。这些组件可以持续存储数据、管理生命周期、模块化你的应用,帮你避免内存泄漏,还能让你不必去写无聊的模板代码。

基本的Android应用需要将数据库与稳健的UI结合起来,新的组件如RoomViewModelLiveDataLifecycle让这个任务变得很简单。他们被设计成像积木一样能彼此组合,下面我们来看看他们是如何工作的:

Room

我们用Room处理数据库,这是一个新的SQLite 对象处理库,想要用Room 设置表,我们可以定义一个Plain Old Java Object(POJO),随后我们用@Entity来标记这个POJO,并创建一个用@PrimaryKey标记的Id。

@Entity
public class Trail{
    public @PrimaryKey String id;
    public String name;
    pubklic double kilometers;
    public int difficulty;
}
复制代码

你需要为每个POJO定义一个数据访问对象(DAO),这里声明的方法代表SQLite命令,用来与你的POJO数据互动

@Dao
public interface TrailDao{
    //Create,read,update,delete examples
    @Insert(onConflict = IGNORE)
    void insertTrail(Trail trail);
    
    @Query("SELECT * FROM Traail")
    public List<Trail> findAllTrails();

    @Update(onConflict = REPLACE)
    void updateTrail(Trail trail);

    @Query("DELETE FROM Trail")
    void deleteAll();
}
复制代码

现在来看看插入和查询的方法,Room 已经将你的POJO对象自动转化为相应的数据表,这个过程是双向的。Room 还会在编译时校验你的SQLite,如果你拼错了什么东西,或是引用了数据库中不存在的列,它会显示一条有用的错误提示。

LiveData

现在你有了Room数据库,你还可以使用另一种构建组件:LiveData ,来监控数据库中的更改。LiveData是一个可观察的数据容器。也就是说,他可以存储数据,还会在数据发生改变时提醒你,这样你就能及时更新UI。LiveData是一个可拓展的抽象类,更简单一点说,你可以使用MutableLiveData类。如果你发出数值更改请求,并更新了MutableLiveData的值,它随后就会在你的UI中触发刷新。更加强大的是,Room自带对LiveData的支持,你可以同时使用它们。 修改你的DAO让它返回用LiveData类包装的对象。

@Dao
public interface TrailDao{
    ....
    @Query("SELECT * FROM Traail")
    public LiveData<List<Trail>> findAllTrails();
    ....
}
复制代码

Room会创建一个LiveData对象用来观察数据库,然后你就可以写出这样的代码来更新你的UI

trailsLiveData.observe(this,trails ->{
    //Update UI, in this case a RecyclerView
    mTrailsRectclerAdapter.replaceItems(trails);
    mTrailsRectclerAdapter.notifyDataSetChanged();
}
复制代码

最终结果是 如果你的Room 数据库更新了,他会改动你的LiveData对象内的数据,从而自动触发UI更新

Lifecycle

不得不说LiveData还有一项很棒的功能,这个组件会留意到生命周期,现在你也许会想,能留意到生命周期的组件是什么东西?我还担心你不会问呢!通过神奇的生命周期观察,LiveData可以了解到你的界面何时再屏幕上出现,何时撤离屏幕,是否已被销毁,它不会向处于非激活状态的UI发送数据库更新。

它有两个接口,分别是:Lifecycle OwnersLifecycle Observers。Lifecycle Owner 是指那些有生命周期的对象,比如Activity和Fragment。Lifecycle Observer则会观察Lifecycle Owner,并且会收到关于生命周期变动的通知。下面来简要介绍一下经过简化的LiveData代码

abstract public class LiveData<T> implements LifecycleObserver{
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void startup() {...}

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void cleanup() {...}
}
复制代码

它同时也是一个Lifecycle Observer。被@OnLifecycleEvent标注的方法,在相关的Lifecycle Owiner开启和停止时,解决了初始化和销毁的问题。这就允许LiveData对象解决自身的建立和销毁问题。UI组件观察LiveData,LiveData组件则观察Lifecycle Owner。对各位Android 代码库设计师们,我还有一点补充,你们可以使用完全相同的生命周期观察代码,来为你自己的代码库自动请求建立和销毁方法。

ViewModel

现在还有一个问题需要解决,你的应用在运行期间,会经历多种配置变化,这些变化会对Activity界面进行破坏和重建。我们不想把LiveData的初始化绑定在生命周期的Activity上,因为这会导致大量无用而重复的代码。这方面的一个例子就是数据库查询,每次你翻转手机时,它都会被执行,那么要怎么办呢?你把你的LiveData和任意其他与UI有关的数据放在ViewModel里。 ViewModel 是一类为UI组件提供数据并能经历多次配置更改而继续存在的对象。创建ViewModel对象时,你需要继承ViewModel类,随后把所有UI中必需的数据放进ViewModel中。

public class TrailListViewModel extends AndroidViewModel{
    private AppDatabase mDatabase;
    private LiveData<List<Trail>> trails;

    public TrailListViewModel(Application application){
        super(application);
        //AppDatabase is a Room database singleton
        //Check the guide for more information
        mDatabase = AppDatabase.getDb(getApplication());
        trails = mDatabase.trailModel().findAllTrails();
    }
    //Getters and setters
}
复制代码

因为你在ViewModel内部为UI缓存了数据,所以如果你的Activity因为配置更改而被重新创建了,你的应用不会对数据库进行查询。随后当你创建Activity或Fragment时,你就可以引用相应的ViewModel并使用它。

//In onCreate
trailListViewModel = ViewModelProviders.of(this)
        .get(TrailListViewModel.class);


//Code to set up the RecyclerView omitted
trailListViewModel.getTrails().observe(this,trails ->{
    mTrailsRectclerAdapter.replaceItems(trails);
    mTrailsRectclerAdapter.notifyDataSetChanged();
}
复制代码

当你第一次得到ViewModel时,它是为你的Activity而生成的,当你再次请求ViewModel时,你的Activity会收到当初生成的ViewModel 和UI 缓存数据。所以不会再有无用的数据库调用了。


总结一下所有这些炫目的构建组件,我们谈到了Room,这是一个为SQLite设计的对象处理库。还有LiveData,它会在数据更改时通知你,这样你就可以更新UI了。重要的是它和Room协作顺畅,所以你可以在数据库数据更改时,轻松更新UI。我们还谈到了Lifecycle Observer 和Owner,他们可以让非UI 对象观察生命周期事件。最后我们还介绍了ViewModel,它会为你提供无法被配置更改破坏的数据对象。他们共同组成了一套构建组件,可以用来编写模块化的、可测试的、强健的Android应用。你可以灵活地搭配运用它们,也可以挑选自己需要的来采用,但这些只是冰山一角而已。事实上,更加久经考验的Android应用,看起来可能是这样的:

关注下面的标签,发现更多相似文章
评论