组件化之路 - LiveData一知半解

嗯,好吧,最近又整理了下JetPack下的Lifecycle、LivaData、ViewModels的相关知识,没想到越学越深,越整理越多,所以赶紧一起共勉一下吧 ~

Android Architecture Components 架构组件

在此之前,我看了很多 LiveData 的相关blog,但是80%的blog都会搭配 ViewModel 进行综合讲解,我此处主要讲解 LiveData 自身的使用与特性 ~

基本认知

众所周知,Google一直有一套属于自己的 Jetpack(组件库) ,而其内部组件又划分为多种类型,分别适用不同场景,其中Lifecycle、LivaData、ViewModel 隶属于 Android Architecture Components(架构化组件)

Android架构化组件是通过提供管理开发者UI 组件的生命周期和数据持久化方案的一系列库,来帮助开发者设计出,稳健性,可测试性和可维护的App应用。

公知:LiveData是一款可被观察的数据持有类组件,内部采用了观察者模式,结合Lifecycle管理组件生命周期等 ~

Look Here 重要的话重复说:正式讲解LiveData前, 一定要记得LiveData是一款可被观察的数据持有类 - 组件

LiveData之所以被开发者广泛使用,其中最重要原因就是其自带的一些特性和优势,具体如下

remark:LiveData内绑定了Lifecycle组件,可动态感知组件的生命周期,所以可以把LiveData看作是一款可感知生命周期的组件

  • 数据实时更新LiveData采用了观察者模式,在注册观察者后,只要被观察者(事件源)发生改变,即可及时捕获最新数据
  • 优化实时更新,生命周期从非活跃状态切换到活跃状态时,才会实时通知LiveData观察者
  • 防止内存泄漏、优化组件销毁的异常场景,当组件生命周期处于DESTROYED时,会自动解除LiveData和观察者的注册关系
  • 优化配置更改,当手机横竖屏切换时也可以及时收到最新的数据
  • 资源共享,单例模式扩展LiveData对象并包装成系统服务,以便在应用程序中进行共享,需要该资源的只需要观察LiveData即可。
原理分析

既然我们说到LiveData使用了观察者模式,自然其具备了一些模式特征,如观察者、被观察者、订阅行为、信息push等要素 ~

LiveData为抽象类,且自身作为被观察者,主要实现类有MutableLiveData、MediatorLiveData子类,其中"MediatorLiveData 继承自 MutableLiveData",所以严格来说LiveData只有一个常用的MutableLiveData 子类 ~

LiveData

在这里插入图片描述

MutableLiveData

在这里插入图片描述

MediatorLiveData(注意:MediatorLiveData 继承自 MutableLiveData)

在这里插入图片描述

观察者部分

LiveData添加的观察者主要有observe、observeForever, 通过方法参数可以看出俩者的区别,observe()需要传入LifecycleOwner(一般写入上下文即可),然后LiveData会自动感知组件的生命周期,在激活状态才会收到消息;而observeForever()会永久收到数据变化的回调,同时当组件销毁时,需要用户手动removeObserve(),否则观察者会一直收到数据的变化的回调通知。

Tip:关于observe()、observeForver()的订阅操作必须在主线程,否则会报异常 ~

observe() - 活跃状态(STARTED、RESUMED状态)期间接收消息

在这里插入图片描述

observeForever()

在这里插入图片描述

被观察者,信息推送部分

LiveData更新(改变)数据时,都有特定的方法(在MutableLiveData类内都可以看到),主要有postValue()、setValue()俩种方式,区别主要体现在setValue()仅支持主线程调用,而postValue()在子主线程中均可被调用(内部使用了handler自主线程通信,最后依旧通过serValue()设值),所以一般我们都使用postValue()

脑补:有时候我在想用EventBus不也ok吗?后来一想使用EventBus为了防止内存泄漏,我要及时注册、注销;同时针对不同组件的生命周期方面,其实又有点浪费性能;所以就算了 ~

postValue()

在这里插入图片描述

setValue()

在这里插入图片描述


入门实践

关于LiveData使用方式主要有俩种,其一使用LiveData对象(子类),其二为继承LiveData(自定义)

综合上述,这里我单独使用 LiveData 写了一个入门Demo

build引入

// alternatively, just LiveData
implementation "android.arch.lifecycle:livedata:1.1.0"

实现步骤

  • 创建被观察者Livedata的实体类
  • 通过observe绑定观察者,动态监听数据更新
  • 通过事件模拟 LiveData - postValue() 动态更新数据
package com.example.livedata;

import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView mName = findViewById(R.id.tv_name);

		//创建被观察者(如果已明确类型,可在泛型内进行申明)
        MutableLiveData<Object> liveData= new MutableLiveData<>();
        //绑定观察者
        liveData.observe(this, new Observer<Object>() {
           @Override
           public void onChanged(Object data) {
               mName.setText(data+"");
           }
       });
       
		//更新数据
        mName.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                liveData.postValue("吾名:LiveData");
            }
        });
    }
}

兴趣扩展

自定义LiveData(尚不完整~)

关于 observe、observeForever、setValue、postValue 方法已经详细讲解过了,这里主要说一下onActive、onInactive方法 ~

  • void onActive ()

Called when the number of active observers change to 1 from 0.
This callback can be used to know that this LiveData is being used thus should be kept up to date.

当这个方法被调用时,表示LiveData的观察者数量从0变为了1,这时就我们的位置监听来说,就应该注册我们的时间监听了。

  • void onInactive ()

Called when the number of active observers change from 1 to 0.
This does not mean that there are no observers left, there may still be observers but their lifecycle states aren’t STARTED or RESUMED (like an Activity in the back stack).
You can check if there are observers via hasObservers().

这个方法被调用时,表示LiveData的观察者数量变为了0,既然没有了观察者,也就没有理由再做监听,此时我们就应该将位置监听移除

Domo示例:这里我们以观察网络状态变化为例子讲解(借鉴自别处,尚未自己这部分)

首先我们自定义一个 Class NetworkLiveData,继承 LiveData,重写它的 onActive 方法和 onInactive 方法

在 onActive 方法中,我们注册监听网络变化的广播,即ConnectivityManager.CONNECTIVITY_ACTION。在 onInactive 方法的时候,我们注销广播。

public class NetworkLiveData extends LiveData<NetworkInfo> {

    private final Context mContext;
    static NetworkLiveData mNetworkLiveData;
    private NetworkReceiver mNetworkReceiver;
    private final IntentFilter mIntentFilter;

    private static final String TAG = "NetworkLiveData";

    public NetworkLiveData(Context context) {
        mContext = context.getApplicationContext();
        mNetworkReceiver = new NetworkReceiver();
        mIntentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
    }

    public static NetworkLiveData getInstance(Context context) {
        if (mNetworkLiveData == null) {
            mNetworkLiveData = new NetworkLiveData(context);
        }
        return mNetworkLiveData;
    }

    @Override
    protected void onActive() {
        super.onActive();
        Log.d(TAG, "onActive:");
        mContext.registerReceiver(mNetworkReceiver, mIntentFilter);
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        Log.d(TAG, "onInactive: ");
        mContext.unregisterReceiver(mNetworkReceiver);
    }

    private static class NetworkReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            ConnectivityManager manager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo activeNetwork = manager.getActiveNetworkInfo();
            getInstance(context).setValue(activeNetwork);
        }
    }
}

这样,当我们想监听网络变化的时候,我们只需要调用相应的 observe 方法即可,方便又快捷。

NetworkLiveData.getInstance(this).observe(this, new Observer<NetworkInfo>() {
    @Override
    public void onChanged(@Nullable NetworkInfo networkInfo) {
        Log.d(TAG, "onChanged: networkInfo=" +networkInfo);
    }
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

远方那座山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值