Android Architecture Components架构下的高效开发

概述

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 mCurrentName;

public MutableLiveData getCurrentName() {
    if (mCurrentName == null) {
        mCurrentName = new MutableLiveData();
    }
    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 nameObserver = new Observer() {
        @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 {
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架构下的高效开发)