Jetpack 架构组件1

391 阅读4分钟

Jetpack架构组件主要用到的又三个Lifecycle,liveData,viewModel。

Lifecycle关联Activity生命周期

Lifecycle使用两个枚举来跟踪其关联组件的生命周期状态,这两个枚举分别是Event和State。 State指的是Lifecycle的生命周期所处的状态。 Event代表Lifecycle生命周期对应的事件,这些事件会映射到Activity和Fragment中的回调事件中

public abstract class Lifecycle {
   
    @MainThread
    public abstract void addObserver(@NonNull LifecycleObserver observer);

    @MainThread
    public abstract void removeObserver(@NonNull LifecycleObserver observer);

    @MainThread
    @NonNull
    public abstract State getCurrentState();

    @SuppressWarnings("WeakerAccess")
    public enum Event {
        ON_CREATE,
        ON_START,
        ON_RESUME,
        ON_PAUSE,
        ON_STOP,
        ON_DESTROY,
        ON_ANY
    }

    @SuppressWarnings("WeakerAccess")
    public enum State {
        DESTROYED,
        INITIALIZED,
        CREATED,
        STARTED,
        RESUMED;
        public boolean isAtLeast(@NonNull State state) {
            return compareTo(state) >= 0;
        }
    }
}

AppCompatActivity继承自FragmentActivity,FragmentActivity中创建了LifecycleRegistry,它是Lifecycle的实现类。在fragmentActivity的各个生命周期中均调用了LifecycleRegistry的handleLifecycleEvent方法,改变Lifecycle的状态,

 final LifecycleRegistry mFragmentLifecycleRegistry = new LifecycleRegistry(this
   /**
     * Dispatch onStart() to all fragments.
     */
    @Override
    protected void onStart() {
        super.onStart();

        mStopped = false;

        if (!mCreated) {
            mCreated = true;
            mFragments.dispatchActivityCreated();
        }

        mFragments.noteStateNotSaved();
        mFragments.execPendingActions();

        // NOTE: HC onStart goes here.

        mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
        mFragments.dispatchStart();
    }

liveData感知生命周期

LiveData 通过调用observe方法来注册观察者,这里的owner就是注册的时候传入的组件,通过获取组件当前的状态如果为DESTROYED直接return说明DESTROYED状态的组件是不被注册的

在注释2处新建了一个LifecycleBoundObserver包装类,将owner和observer传了进去。 注释3处将observer和LifecycleBoundObserver存储到SafeIterableMap, ObserverWrapper>mObservers中,putIfAbsent方法和put方法有区别,如果传入key对应的value已经存在,就返回存在的value,不进行替换。如果不存在,就添加key和value,返回null。 如果等于null,在注释4处会将LifecycleBoundObserver添加到Lifecycle中完成注册,这样当我们调用LiveData的observe方法时,实际上是LiveData内部完成了Lifecycle的观察者的添加,这样LiveData自然也就有了观察组件生命周期变化的能力。LiveData并不是通知所有观察者,它只会通知处于Active状态的观察者,如果一个观察者处于DESTROYED状态,它将不会收到通知

LifecycleBoundObserver继承了ObserverWrapper类,重写了shouldBeActive方法,用于判断当前传入的组件的状态是否是Active的,Active状态包括STARTED和RESUMED状态。 LifecycleBoundObserver实现了GenericLifecycleObserver接口,当组件状态发生变化时,会调用onStateChanged方法,当组件处于DESTROYED状态时,会调用removeObserver方法,来移除observer。

@MainThread
   public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
       assertMainThread("observe");
       //如果被观察者的当前的状态是DESTROYED,就return
       if (owner.getLifecycle().getCurrentState() == DESTROYED) {//1
           return;
       }
       LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);//2
       ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);//3
       if (existing != null && !existing.isAttachedTo(owner)) {
           throw new IllegalArgumentException("Cannot add the same observer"
                   + " with different lifecycles");
       }
       if (existing != null) {
           return;
       }
       owner.getLifecycle().addObserver(wrapper);//4
   }

当调用MutableLiveData的observe方法后,还需要通过postValue/setValue方法来更新数据。setValue方法是运行在主线程中的,postValue实际上就是切到主线程中调用setValue方法

viewModel使用

创建一个MutableLiveData,并通过MutableLiveData的postValue方法来更新数据,实现

final MutableLiveData<Boolean> data = new MutableLiveData<>();
        RequestManager.getInstance().addFavorites(request).
                subscribe(new HttpResultCallBack<ResponseData<String>>() {
                    @Override
                    public void onSuccess(ResponseData<String> bean) {
                        data.postValue(bean.isSuccessful());
                    }

                    @Override
                    public void onError(ResponseData<String> result, int code, String msg) {
                        ToastUtils.showShort(msg);
                        data.postValue(false);
                    }
                });

来看看我们是如何初始化viewModel的

根据key值从ViewModelStore中获取viewModel如果ViewModel能转换为modelClass类的对象,直接返回该ViewModel。否则会通过Factory创建一个ViewModel,并将其存储到ViewModelStore中。这里的Factory指的是AndroidViewModelFactory,它在ViewModelProvider创建时作为参数传进来。

    /**
     * 初始化ViewModel
     */
    private void initViewModel() {
        Class<VM> viewModelClass = ClassUtil.getViewModel(this);
        if (viewModelClass != null) {
            this.viewModel = ViewModelProviders.of(this).get(viewModelClass);
        }
    }
    @NonNull
    @MainThread
    public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
        ViewModel viewModel = mViewModelStore.get(key);

        if (modelClass.isInstance(viewModel)) {
            if (mFactory instanceof OnRequeryFactory) {
                ((OnRequeryFactory) mFactory).onRequery(viewModel);
            }
            return (T) viewModel;
        } else {
            //noinspection StatementWithEmptyBody
            if (viewModel != null) {
                // TODO: log a warning.
            }
        }
        if (mFactory instanceof KeyedFactory) {
            viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
        } else {
            viewModel = (mFactory).create(modelClass);
        }
        mViewModelStore.put(key, viewModel);
        return (T) viewModel;
    }

根据viewModel单一实例的特性以及生命周期跟随application,viewModel的另外一个功能是可以用于数据共享。具体见如下demo

public class FabricDetailsModel extends AndroidViewModel {
     private MutableLiveData<FabricDetailsBean> testData = new MutableLiveData<>();
     public MutableLiveData<FabricDetailsBean> getFabricDetails(FabricDetailsRequest request){
        if(testData ==null){
            testData = new MutableLiveData<>();
            RequestManager.getInstance().getFabricDetails(request).
                    subscribe(new HttpResultDataCallBack<FabricDetailsBean>() {
                        @Override
                        public void onSuccess(FabricDetailsBean bean) {
                            testData.postValue(bean);
                        }

                        @Override
                        public void onError(FabricDetailsBean bean, int code, String msg) {
                            ToastUtils.showShort(msg);
                            testData.postValue(null);
                        }
                    });
        }
        return testData;
    }
    public MutableLiveData<FabricDetailsBean> getTestData() {
        return testData;
    }

    public void setTestData(MutableLiveData<FabricDetailsBean> testData) {
        this.testData = testData;
    }
}
public class TestActivity extends BaseActivity <AndroidViewModel, FabricDetailsActivityBinding>{
    @Override
    public int getContentView() {
        return R.layout.fabric_details_activity;
    }

    @Override
    protected void initView() {
        FabricDetailsModel myViewMode = new ViewModelProvider(this).get(FabricDetailsModel.class);
        myViewMode.getTestData().observe(this, bean -> {

        });
    }

    @Override
    public void initData() {

    }
}