ArchitectureComponent

栏目: 编程语言 · Java · 发布时间: 6年前

内容简介:架构库参考文献Demo

架构库

  • LiveData

    数据变更观察者, 我觉得和DataBinding的Observable接口发生冲突

  • ViewModel

    解耦数据脱离组件, 防止意外销毁

  • Lifecyle

    分离生命周期

  • Room

    (推荐使用Realm替代, Reaml+RxJava可以替代Room+LiveData, 并且更加强大)

  • DataBinding

    数据和Ui的双向绑定, 数据变更观察者

参考文献

Demo

android-lifecycles : 关于lifecycle/viewModule/liveData的示例

android-architecture-components

Retrofit+Okhttp
Dagger2

导入依赖

完整依赖

dependencies {
    // ViewModel and LiveData
    implementation "android.arch.lifecycle:extensions:1.0.0"
    annotationProcessor "android.arch.lifecycle:compiler:1.0.0"

    // Room
    implementation "android.arch.persistence.room:runtime:1.0.0"
    annotationProcessor "android.arch.persistence.room:compiler:1.0.0"

    // Paging
    implementation "android.arch.paging:runtime:1.0.0-alpha4-1"

    // Test helpers for LiveData
    testImplementation "android.arch.core:core-testing:1.0.0"

    // Test helpers for Room
    testImplementation "android.arch.persistence.room:testing:1.0.0"
}

lifecycle已被support library实现无需导入

dependencies {
    // RxJava support for Room
    implementation "android.arch.persistence.room:rxjava2:1.0.0"

    // ReactiveStreams support for LiveData
    implementation "android.arch.lifecycle:reactivestreams:1.0.0"
}

ViewModule

之前数据常常被保存在组件之中(例如在activity中创建的成员变量)

但是由于内存不足, 组件常常会遭到系统的清除, 这样会导致数据被清空(intent中的数据不会被清空), 就需要再次去请求服务器数据这样会导致体验不够流畅并且浪费流量.

所以组件不应该保存任何数据.

创建ViewModule

public class LiveDataTimerViewModel extends ViewModel {
  /**/
}

绑定生命周期(或者说获取ViewModule的实例)

mLiveDataTimerViewModel = ViewModelProviders.of(this).get(LiveDataTimerViewModel.class);

其保存的数据和组件并不发生关系. 如果意外销毁后数据依旧是之前的数据不会重建(脱离于组件生命周期的数据)

并且在多个组件之间ViewModule的数据是可以共享的.

ViewModelProviders

使用该类的静态方法来创建ViewModelProvider实例

static ViewModelProvider	of(Fragment fragment)

static ViewModelProvider	of(FragmentActivity activity)

static ViewModelProvider	of(Fragment fragment, ViewModelProvider.Factory factory)

static ViewModelProvider	of(FragmentActivity activity, ViewModelProvider.Factory factory)

Factory可以用来创建你需要有参构造方法的ViewModule

ViewModelProvider

<T extends ViewModel> T	get(Class<T> modelClass)

<T extends ViewModel> T	get(String key, 
                            Class<T> modelClass)

AndroidViewModel

继承这个类主要是可以拿到上下文Application.

查看源码:

public class AndroidViewModel extends ViewModel {
    @SuppressLint("StaticFieldLeak")
    private Application mApplication;

    public AndroidViewModel(@NonNull Application application) {
        mApplication = application;
    }

    /**
     * Return the application.
     */
    @NonNull
    public <T extends Application> T getApplication() {
        //noinspection unchecked
        return (T) mApplication;
    }
}

推荐使用 DefaultFactory 来创建他

ViewModelProviders.of(this, new ViewModelProviders.DefaultFactory(getApplication())).get(MyViewModule.class);

LiveData

使数据变成一个可被观察状态, 并且符合视图的生命周期.

在活跃状态观察者可以接受到事件, 不活跃状态观察者不会接收到事件. 如果生命周期所有者被破坏自动删除观察者.

IllegalArgumentException

全部方法

T	getValue() 
// 返回当前值

boolean	hasActiveObservers() 
// 是否有被激活的观察者(处于活跃状态)

boolean	hasObservers() 
// 是否有观察者

void	observe(LifecycleOwner owner, 
                Observer<T> observer)

void	observeForever(Observer<T> observer)
// 添加一个永远处于活跃状态的观察者(并且不会自动删除观察者), 所以需要你自己删除观察者
// 重复添加同一个观察者会抛出IllegalArgumentException

void	removeObserver(Observer<T> observer)
// 删除观察者

void	removeObservers(LifecycleOwner owner)
// 删除生命周期

这是一个抽象类, 我们一般都是用他的子类 MutableLiveData<T>

在ViewModel中创建liveData字段

一般情况下在ViewModel中创建字段, 但是也可以在任何模块下使用来解耦.

private MutableLiveData<Long> mElapsedTime = new MutableLiveData<>();

在数据变化后调用方法设置值(根据所处线程不同而调用不同的方法)

mElapsedTime.setValue(newValue); // 主线程

mElapsedTime.postValue(newValue); // 后台线程

然后在 Lifecycle 中注册观察者

final Observer<Long> elapsedTimeObserver = new Observer<Long>() {
  @Override
  public void onChanged(@Nullable final Long aLong) {

// 在观察者中更新ui
    String newText = ChronoActivity3.this.getResources().getString(
      R.string.seconds, aLong);

  }
};

// 拿到LiveData然后绑定观察者
mLiveDataTimerViewModel.getElapsedTime().observe(this, elapsedTimeObserver);

如果在添加观察者之前已经设置值, 同样会回调一次观察者.

MutableLiveData

这个继承liveData(abstract). 只是公开了了两个私有方法

以下为全部源码:

public class MutableLiveData<T> extends LiveData<T> {
  
    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

扩展LiveData

可以通过继承LiveData来实现

public class MyLiveData extends LiveData<String> {
  /**
   * 活跃状态
   */
  @Override protected void onActive() {
    super.onActive();
  }

  /**
   * 非活跃状态
   */
  @Override protected void onInactive() {
    super.onInactive();
  }
}

要想触发这两个方法必须要绑定观察者.

其实实现 LifecycleObserver 也能够实现生命周期的回调. 但是LiveData可以设置观察者

数据转换

Transformations 提供两个方法, 类似于RxJava的操作符.

static <X, Y> LiveData<Y>	map(LiveData<X> source, Function<X, Y> func)

static <X, Y> LiveData<Y>	switchMap(LiveData<X> trigger, Function<X, LiveData<Y>> func)

示例:

final MyLiveData myLiveData = new MyLiveData();

    myLiveData.observe(this, new Observer<String>() {
      @Override public void onChanged(@Nullable String s) {
      }
    });

    final LiveData<Integer> transformationLiveData =
        Transformations.map(myLiveData, new Function<String, Integer>() {
          /**
           * 如果想要该方法回调需要结果LiveData设置观察者才行
           *
           * @param input 源LiveData存储的数据
           * @return 最终返回的LiveData存储的数据
           */
          @Override public Integer apply(String input) {
            return 2;
          }
        });

    transformationLiveData.observe(this, new Observer<Integer>() {
      @Override public void onChanged(@Nullable Integer integer) {
        
      }
    });

switchMap方法需要返回一个LiveData. 这个LiveData就是最终的结果

final LiveData<Integer> transformationLiveData =
  Transformations.switchMap(myLiveData, new Function<String, LiveData<Integer>>() {
    /**
           * @param input 源数据
           * @return 返回结果等于switchMap的结果
           */
    @Override public LiveData<Integer> apply(String input) {
      MutableLiveData<Integer> transformationLiveData = new MutableLiveData<>();
      transformationLiveData.setValue(3);
      return transformationLiveData;
    }
  });

MediatorLiveData

可以设置多个源(LiveData). 然后通过观察者来监听多个LiveData的变化

<S> void	addSource(LiveData<S> source, Observer<S> onChanged)
// 添加源

<S> void	removeSource(LiveData<S> toRemote)
// 删除源

查看Transformation的源码也可以看到实际上就是运用MediatorLiveData.

@MainThread
public static <X, Y> LiveData<Y> map(@NonNull LiveData<X> source,
                                     @NonNull final Function<X, Y> func) {
  final MediatorLiveData<Y> result = new MediatorLiveData<>();
  result.addSource(source, new Observer<X>() {
    @Override
    public void onChanged(@Nullable X x) {
      result.setValue(func.apply(x));
    }
  });
  return result;
}

Lifecycle

生命周期组件, 可以将一个类赋予生命周期.

SupportLibrary的组件中都已经实现了 LifecycleOwer (例如 AppCompatActivity ), 所以我们可以在activity当中直接使用Lifecycle方法.

使用

需要绑定生命周期的类实现接口 LifecycleObserver

public class MyLifecycle implements LifecycleObserver {}

将当前类作为观察者传入(lifecycleOwner一般由构造方法传入)

lifecycleOwner.getLifecycle().addObserver(this);

然后就可以通过注解来在生命周期时自动调用

@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
        void removeLocationListener() {
            if (mLocationManager == null) {
                return;
            }
            mLocationManager.removeUpdates(mListener);
            mLocationManager = null;
            Log.i("日志", "(BoundLocationListener.java:74) ___ removeLocationListener");
        }
    }

所有的生命周期状态

public enum Event {
      
        ON_CREATE,
        
        ON_START,
       
        ON_RESUME,
        
        ON_PAUSE,
        
        ON_STOP,
        
        ON_DESTROY,
        
        ON_ANY
    }

执行顺序

ArchitectureComponent

如果你想自定义LifecycleOwner也可以

public class MyActivity extends Activity implements LifecycleOwner {
    private LifecycleRegistry mLifecycleRegistry;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mLifecycleRegistry = new LifecycleRegistry(this);
        mLifecycleRegistry.markState(Lifecycle.State.CREATED);
    }

    @Override
    public void onStart() {
        super.onStart();
        mLifecycleRegistry.markState(Lifecycle.State.STARTED);
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }
}

生命周期状态

通过LifecycleOwer获取Lifecycle实例然后得到状态

getLifecycle().getCurrentState()

有五种状态

Lifecycle.State 	CREATED

Lifecycle.State 	DESTROYED

Lifecycle.State 	INITIALIZED
. 
Lifecycle.State 	RESUMED

Lifecycle.State 	STARTED

ON_CREATE , ON_START , ON_RESUME 比其依附Activityd的生命周期方法要晚回调. 但是 ON_PAUSE , ON_STOP , ON_DESTROY 则要早回调.

生命周期注解

上面提到了用注解来控制生命周期, 但是这只在 java 7之前有用. 在java8之后需要导入一个新的依赖

这意味着在java8全面使用在android上时, 注解方法将被放弃.

dependencies {
    // Java8 support for Lifecycles
    implementation "android.arch.lifecycle:common-java8:1.0.0"
}

并且不再使用注解而是使用重写方法, 并且实现 DefaultLifecycleObserver

class TestObserver implements DefaultLifecycleObserver {
     @Override
     public void onCreate(LifecycleOwner owner) {
         // your code
     }
 }

生命周期方法参数

只能有一个或者没有参数, 但是可以增加一个 LifecycleOwner 参数. 并且 ON_ANY 注解的方法可以增加第二个注解 Event . 该参数的作用只是判断当前所处的生命周期.

class TestObserver implements LifecycleObserver {
   @OnLifecycleEvent(ON_CREATE)
   void onCreated(LifecycleOwner source) {}
   @OnLifecycleEvent(ON_ANY)
   void onAny(LifecycleOwner source, Event event) {}
 }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

海量运维、运营规划之道

海量运维、运营规划之道

唐文 / 电子工业出版社 / 2014-1-1 / 59.00

《海量运维、运营规划之道》作者具有腾讯、百度等中国一线互联网公司多年从业经历,书中依托工作实践,以互联网海量产品质量、效率、成本为核心,从规划、速度、监控、告警、安全、管理、流程、预案、考核、设备、带宽等方面,结合大量案例与读者分享了作者对互联网海量运维、运营规划的体会。 《海量运维、运营规划之道》全面介绍大型互联网公司运维工作所涉及的各个方面,是每个互联网运维工程师、架构师、管理人员不可或......一起来看看 《海量运维、运营规划之道》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

MD5 加密
MD5 加密

MD5 加密工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换