Android Architecture Components架

作者: Android高级开发 | 来源:发表于2019-02-19 16:29 被阅读6次

    概述

    Android Architecture Components是一系列库集合,能帮助你设计出健壮的,可测试的,可维护的应用。使用几个类,来管理UI组件的生命周期和处理数据持久化。

    • 管理app的生命周期很轻松。新的lifecycle-aware components组件,能帮助你管理activity/fragment的生命周期。保存配置更改,避免内存泄漏并轻松加载数据。

    • 使用LiveData构建数据对象,在底层数据库更改时通知视图。

    • ViewModel存储UI相关数据,这些数据不会在应用旋转中被销毁。

    • Room是一个SQLite对象映射库。使用它避免样板代码,并容易地将SQLite表数据转换为Java对象。提供SQLite语句的编译时检查,并可以返回RxJava,Flowable和LiveData可观察对象。

    架构图

    推荐使用官方架构,模块的交互方式如下:

    Picture

    生命周期感知组件

    感知生命周期的组件执行动作,以响应其他组件(如Activity和Fragment)的生命周期状态的变化。这些组件有助于产生更好的组织性和更轻的重量代码,这更易于维护。

    一种常见的模式是在Activity和Fragment的生命周期方法中实现依赖组件的动作。然而,这种模式导致代码的组织和错误扩散。通过使用生命周期感知组件,可以将依赖组件的代码从生命周期方法中移出并移入组件本身。

    生命周期包提供了允许您构建生命周期感知组件的类和接口,这些组件可以根据Activity和Fragment的当前生命周期状态自动调整它们的行为。

    Lifecycle-Aware Components,主要包含三个基本接口:

    • LifecycleOwner

    interface LifecycleOwner {
    getLifecycle();
    }
    在FragmentActivity和Fragment实现,返回Lifecycle对象,用来给外部管理生命周期状态。

    • Lifecycle

    Lifecycle对象,能观察LifecycleObserver对象,并返回当前LifecycleOwner的生命周期状态(started,created)。

    • LifecycleObserver

    实现LifecycleObserver的类,能通过注解的方式,接收到状态变化的通知。如:

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    void onCreate(LifecycleOwner lifecycleOwner) {
    }
    
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    void onResume(LifecycleOwner lifecycleOwner) {
    }
    

    比如,ViewModel类实现了LifecycleObserver接口,在Activity里添加getLifecycle().addObserver(viewModel);
    那ViewModel就有了生命周期感知功能。

    在Android框架中定义的大多数应用程序组件都有生命周期。生命周期是由操作系统或运行在您的进程中的框架代码管理的。它们是Android工作的核心,你的应用程序必须尊重它们。不这样做可能触发内存泄漏或甚至应用崩溃。

    想象一下,我们有一个Activity显示屏幕上的设备位置。一个常见的实现方式可能如下:

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

    用了Lifecycle,还可以这样:

    public class MyObserver implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void connectListener() {
        ...
    }
    
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void disconnectListener() {
        ...
    }
    }
    
    myLifecycleOwner.getLifecycle().addObserver(new MyObserver());
    

    是不是清晰很多。

    LiveData

    LiveData是一个可观测的数据保持类。与常规观察不同,LiveData是生命周期感知的,这意味着它尊重其他应用程序组件(如Activity、Fragment或Service)的生命周期。这种感知确保LiveData只更新处于活跃生命周期状态的应用程序组件观察者。

    您可以注册一个与实现 LifecycleOwner 接口的对象配对的观察者。这种关系允许当相应 ([https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.html)[|](https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.html)[%7C)60d8d77e15b1b69c7a3cfbc6b952b9393 |]对象的状态改变为([https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.State.html#DESTROYED)[|](https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.State.html#DESTROYED)[|) 60d8d77e15b1b69c7a3cfbc6b952b9394 |]时观察者被移除。这对于Activity和Fragment尤其有用,因为它们可以安全地观察 ([https://developer.android.google.cn/reference/android/arch/lifecycle/LiveData.html)|[%7C)60d8d77e15b1b69c7a3cfbc6b952b9395 |]对象,而不用担心泄漏——当Activity或Fragment的生命周期被销毁时,它们会立即取消订阅。
    有关如何使用LiveData的更多信息,请参见使用LiveData对象

    使用LiveData的优势

    • 确保UI与数据状态匹配
      LiveData遵循观察者模式。当生命周期状态改变时,LiveData通知观察者对象。您可以合并代码来更新这些观察对象中的UI。每次应用程序数据更改时,都不更新UI,观察者可以每次更改时更新UI。

    • 没有内存泄漏
      观察者绑定到生命周期对象,并在其关联的生命周期被销毁后自行清理。

    • 停止Activity时的崩溃
      如果观察者的生命周期是不活动的,比如在后堆栈中的活动,那么它不接收任何LiveData事件。

    • 无需手动处理生命周期
      UI组件只是观察相关数据,不停止或恢复观察。LiveData自动管理所有这一切,因为它意识到相关的生命周期状态变化,同时观察。

    • 始终保持最新数据
      如果生命周期变得不活动,则在再次激活时接收最新数据。例如,后台中的Activity在返回到前台后立即接收最新数据。

    • 正确的配置改变
      如果由于配置改变而重新生成Activity或Fragment,例如设备旋转,则它立即接收最新可用数据。

    • 资源共享
      您可以使用Sigelon模式扩展LiveData对象来包装系统服务,以便它们可以在您的应用程序中共享。LiveData对象连接到系统服务一次,然后需要该资源的任何观察者都可以只观察LiveData对象。有关更多信息,请参见扩展LiveData

    如何使用LiveData

    按照以下步骤使用LiveData对象:

    • 创建一个LiveData实例来保存某种类型的数据。这通常是在ViewModel类中完成的。

    • 创建一个Observer对象,该对象定义onChanged()方法,该方法控制LiveData对象保存的数据更改时发生的情况。通常在UI控制器,例如Activity或Fragment中,创建一个Observer对象。

    • 使用 observe()60d8d77e15b1b69c7a3cfbc6b952b93910 |]方法传入([https://developer.android.google.cn/reference/android/arch/lifecycle/LifecycleOwner.html)|[%7C)60d8d77e15b1b69c7a3cfbc6b952b93911 |]对象。这将观察对象向LiveData对象订阅,以便通知其更改。通常将观察者对象附加在UI控制器中,例如Activity或Fragment。

    • 当更新LiveData对象中存储的值时,只要所附的LifecycleOwner处于活动状态,就会触发所有已注册的观察器。
      LiveData允许UI控制器观察员订阅更新。当LiveData对象保存的数据发生变化时,UI会自动响应更新。

    创建LiveData

    public class NameViewModel extends ViewModel {
    
    // Create a LiveData with a String
    private MutableLiveData<String> mCurrentName;
    
    public MutableLiveData<String> getCurrentName() {
        if (mCurrentName == null) {
            mCurrentName = new MutableLiveData<String>();
        }
        return mCurrentName;
    }
    
    // Rest of the ViewModel...
    }
    

    观察LiveData

    public class NameActivity extends AppCompatActivity {
    
    private NameViewModel mModel;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        // Other code to setup the activity...
    
        // Get the ViewModel.
        mModel = ViewModelProviders.of(this).get(NameViewModel.class);
    
        // Create the observer which updates the UI.
        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(@Nullable final String newName) {
                // Update the UI, in this case, a TextView.
                mNameTextView.setText(newName);
            }
        };
    
        // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
        mModel.getCurrentName().observe(this, nameObserver);
    }
    }
    

    扩展LiveData

    LiveData认为观察者必须在有效状态,无论是在STARTED或([https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.State.html#RESUMED)|[|) 60d8d77e15b1b69c7a3cfbc6b952b93914 |]状态,可以用来做全局数据共享,
    下面的示例代码说明如何扩展LiveData类:

    public class StockLiveData extends LiveData<BigDecimal> {
    private StockManager mStockManager;
    
    private SimplePriceListener mListener = new SimplePriceListener() {
        @Override
        public void onPriceChanged(BigDecimal price) {
            setValue(price);
        }
    };
    
    public StockLiveData(String symbol) {
        mStockManager = new StockManager(symbol);
    }
    
    @Override
    protected void onActive() {
        mStockManager.requestPriceUpdates(mListener);
    }
    
    @Override
    protected void onInactive() {
        mStockManager.removeUpdates(mListener);
    }
    }
    

    多种场景下的使用

    Activity/Fragment
    最基本的UI场景,只需要在Activity/Fragment调用observe()方法关注LiveData数据,即可。
    需要注意的是,使用Activity/Fragment都是LifecycleOwner对象,需要哪个LifecycleOwner就看业务需要。

    ViewHolder
    比如在RecyclerView的ViewHolder里面观察LiveData,因为ViewHolder有缓存机制,所以Observer跟item并不一对一。一般可以在初始化ViewHolder时,观察LiveData,然后接收到数据变更,则修改item数据,并重修刷新ui。这样才能做到兼容ViewHolder机制。

    View/ViewGroup
    如果View不涉及到销毁(重建)的情况,也不需要理会Observer,否则,也要管理Observer的观察和取消观察。

    UI组件以外
    UI组件以外,需要用到observeForever()方法,此方法没有生命周期感知,需要手动管理取消观察。

    ViewModel管理LiveData和全局LiveData的区别
    本质上没有不同,主要在于数据本身生命周期的需要和共享的需要。
    比如ViewModel的LiveData会随着Activity/Fragment产生、共享和销毁,而全局的LiveData是跟随进程或手动管理的。

    LiveData的创建场景和观察场景
    LiveData能在任何地方,任何情况创建。
    观察场景可以在UI组件使用observe()/observeForever()方法,或其他非UI场景只能用observeForever()方法。

    附言
    以上为个人的经验总结,不当之处欢迎讨论,并持续优化。

    image image

    +qq群:853967238。获取以上高清技术思维图,以及相关技术的免费视频学习资料

    相关文章

      网友评论

        本文标题:Android Architecture Components架

        本文链接:https://www.haomeiwen.com/subject/rgjfyqtx.html