android-architecture-components的简单使用分析

    近期读了一下Google的architecture-components框架的示例代码,记下自己目前所能理解的东西吧。

    Google示例代码的github地址

    https://github.com/googlesamples/android-architecture-components

先简单介绍一下该框架的主要内容(看了部分源码,还不是很清晰,后面尽量补源码分析,下面只记录一些简单用法):

一、LifecycleObserver

    用于观察Activity、Fragment等的生命周期,记录当前的活跃状态,可以在LifecycleObserver对Activity生命周期进行监听,处理相关事件,也可以获取当前的状态。下面是简单的使用方式

public class BaseObserver implements LifecycleObserver {
    private static final String TAG = BaseObserver.class.getSimpleName();

    public BaseObserver(Lifecycle lifecycle)
    {
        lifecycle.addObserver(this);
        Log.i(TAG,"BaseObserver");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void resume()
    {
        Log.i(TAG,"resume");
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    public void stop()
    {
        Log.i(TAG,"stop");
    }
}

Lifecycle为一个抽象类,负责绑定Observer,Activity继承于AppCompatActivity后,其最终继承的SupportActivity实现了LifecycleOwner接口,并且该类里会有Lifecycle的实现,可以直接调用getLifecycle()方法获取Lifecycle对象。

调用Lifecycle的addObserver()方法即可将Observer和Activity绑定在一起。

可以用注解标记对应的生命周期,在对应生命周期执行时,就会调用Observer的对应方法,避免在Activity的生命周期中书写大量代码,导致不易维护。

public class ObserverActivity extends AppCompatActivity{
    BaseObserver observer ;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        observer = new BaseObserver(getLifecycle());
    }
}
Activity中可以简单地创建Observer,绑定之后即可生效


二、LiveData

LiveData是进行数据存储的,可以被观察,与普通的被观察者不同,LiveData遵循观察者的生命周期,如果不在活跃状态,不会向观察者发送数据改变的信息。

LiveData的简单使用

public class LiveDataActivity extends AppCompatActivity {
    private static final String TAG = LiveDataActivity.class.getSimpleName();
    private MutableLiveData liveData;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        liveData = new MutableLiveData<>();
        liveData.setValue(null);
        liveData.observe(this, new Observer() {
            @Override
            public void onChanged(@Nullable String s) {
                Log.i(TAG,"s = " + s);
            }
        });
        liveData.setValue("String");
        new Handler().postDelayed(() -> liveData.setValue("new String"),1000);

    }
}

MutableLiveData继承鱼LiveData,其实现了setValue()和postValue()方法(只是将方法改为了public的)。

上述代码执行后,会在onChange中先打印出“String”,在一秒后,再次调用onChange方法,打印“new String”。

setValue和postValue均为向LiveData更新数据 

按照源码中的解释,setValue必须在主线程中使用,在子线程中需要使用postValue进行数据的更新。

    /**
     * Sets the value. If there are active observers, the value will be dispatched to them.
     * 

* This method must be called from the main thread. If you need set a value from a background * thread, you can use {@link #postValue(Object)} * * @param value The new value */ @MainThread protected void setValue(T value) { assertMainThread("setValue"); mVersion++; mData = value; dispatchingValue(null); }


三、ViewModel

ViewModel的目的是在页面销毁等情况,仍然能够将数据存储下来,再下次创建该页面的时候,直接获取到销毁之前的数据而不是重新加载,可以大幅提升apk的性能,比onSaveInstanceState更加好用,存储的数据范围更广。

由于ViewModel的目的是在页面销毁等场景处理,故不要再ViewModel中持有某个Acvtivity的Context对象,否则会造成内存泄漏。

ViewModel的简单使用:

public class BaseViewModel extends AndroidViewModel {
    private MutableLiveData> users;
    private Handler mHandler = new Handler();
    private int index;
    public BaseViewModel(Application application) {
        super(application);
    }

    public LiveData> getUsers()
    {
        if(null == users)
        {
            users = new MutableLiveData<>();
            users.setValue(null);
            loadUsers();
        }
        return users;
    }

    private void loadUsers() {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                List userList = new ArrayList<>();
                userList.add(new User("Bob",index++));
                users.postValue(userList);
                mHandler.postDelayed(this,2000);
            }
        },2000);
    }
}
public class MainActivity extends BaseActivity {


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView contentTextView = findViewById(R.id.txt);
        viewModel = ViewModelProviders.of(this).get(BaseViewModel.class);
        viewModel.getUsers().observe(this, users -> {
            Log.i("mtfTest","users  = " + users);
            contentTextView.setText(null == users ? "users is null" : users.toString());
        });
    }
}

ViewModel一般结合LiveData使用,LiveData的数据存放在ViewModel中。

ViewModel的创建使用ViewMpdelProviders这个类,其原理是如果没有该ViewModel类的对象,就创建新的对象,如果已有ViewModel对象,就取出旧的ViewModel对象,这样Activity在销毁重建后,还是能取出之前的数据,节省掉了重复加载数据的场景。

ViewModel创建的简单流程:

 /**
     * Returns an existing ViewModel or creates a new one in the scope (usually, a fragment or
     * an activity), associated with this {@code ViewModelProvider}.
     * 

* The created ViewModel is associated with the given scope and will be retained * as long as the scope is alive (e.g. if it is an activity, until it is * finished or process is killed). * * @param modelClass The class of the ViewModel to create an instance of it if it is not * present. * @param The type parameter for the ViewModel. * @return A ViewModel that is an instance of the given type {@code T}. */ public T get(Class modelClass) { String canonicalName = modelClass.getCanonicalName(); if (canonicalName == null) { throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels"); } return get(DEFAULT_KEY + ":" + canonicalName, modelClass); } /** * Returns an existing ViewModel or creates a new one in the scope (usually, a fragment or * an activity), associated with this {@code ViewModelProvider}. *

* The created ViewModel is associated with the given scope and will be retained * as long as the scope is alive (e.g. if it is an activity, until it is * finished or process is killed). * * @param key The key to use to identify the ViewModel. * @param modelClass The class of the ViewModel to create an instance of it if it is not * present. * @param The type parameter for the ViewModel. * @return A ViewModel that is an instance of the given type {@code T}. */ @NonNull @MainThread public T get(@NonNull String key, @NonNull Class modelClass) { ViewModel viewModel = mViewModelStore.get(key); if (modelClass.isInstance(viewModel)) { //noinspection unchecked return (T) viewModel; } else { //noinspection StatementWithEmptyBody if (viewModel != null) { // TODO: log a warning. } } viewModel = mFactory.create(modelClass); mViewModelStore.put(key, viewModel); //noinspection unchecked return (T) viewModel; }

在源码中可以看到,创建之后会存在mViewModelStore中(实际里面是一个HashMap),如果已经创建过的ViewModel,直接从Map中取出即可。

对于相同的类,可以设定不同的key创建多个对象。

四、小结

        LifecycleObserver的作用是监听Activity的生命周期,可以根据生命周期做对应的处理,比如LiveData的内部实现就是通过LifecycleObserver做的监听,判断是否活跃,在活跃状态才会通知Observer进行更新。

        LiveData的主要作用是数据存储,通过Observer的回调,通知数据改变,并且只在观察者活跃状态才会通知。

        ViewModel的强大在于,可以将数据与Activity独立区分,使数据不收Activity的生命周期影响,在Activity销毁重建等场景,不再重复请求加载数据。

        同样,该框架不局限于Activity,在Fragment等组件中也适用,使用方法差不多。

你可能感兴趣的:(Android)