安卓LiveData,自定义消息管理

        上一回仅仅是初次使用EventBus与LiveData,个人感觉EventBus并不适合自己,LiveData才是自己想要的,但是,LiveData的通知管理很蛋疼,所以自己使用了多个LiveData实例,当时感觉美滋滋的。最近,感觉很不爽,就这么几个实例,开始寻找执行轨迹的时候,已经很麻烦了,难道以后还要继续增加实例,不可能,程序员的奥义,完全重复的方法体,有且只有一个就可以了。so,我又想到了一个好办法。

        本次依然不讲源码,那不是我的实力允许的,这里只讲思路以及自己的具体代码

一、创建ViewModel

这个是LiveData传递数据的基础,直接来吧

public class MyLiveDataViewModel implements Serializable {

    public static final long serialVersionUID = 38L;

    /**
     * 无事发生
     */
    public static final int DEFAULT = -1;

    public static final int userList = 1000; (对应flag)//客户列表
    public static final int userListFresh = 10001;(对应type)
    public static final int userListFresh2 = 10002;(对应type)

        /**
     * 初始化
     *
     * @param flag   标记,类似信道,
     * @param type   操作方法标记
     * @param object 传值(ps:如果没有固定的类,可用Bundle来当这个Object)
     */
    public MyLiveDataViewModel(int flag, int type, Object object) {
        this.map = new HashMap<>();
        map.put(flag, type);
        map.put(type, object);
    }

    private Map<Integer, Object> map;

    public Map<Integer, Object> getMap() {
        if (map == null) {
            map = new HashMap<>();
        }
        return map;
    }

    private void setMap(Map<Integer, Object> map) {
        this.map = map;
    }


    //给实例化后的viewModel进行赋值
    public void putData(int flag, int type, Object object) {
        getMap().put(flag, type);
        getMap().put(type, object);
    }

    //自定义已读消息,将flag标记对应的value设为DEFAULT
    public void clean(int flag) {
        map.put(flag, DEFAULT);
    }

    //获取flag对应的value(对应type),如果无值或者被标记为DEFAULT,表示消息已读或者无消息
    public Integer getType(int flag) {
        if (map != null) {
            if (map.get(flag) == null) {
                return DEFAULT;
            }
            return (Integer) map.get(flag);
        }
        return DEFAULT;
    }

    //获取type对应的value(对应Object)
    public Object getObject(int type) {
        if (map != null) {
            return map.get(type);
        }
        return null;
    }

   
    //打印已保存的消息数据
    public void showLog() {
        if (map != null) {
            StringBuilder builder = new StringBuilder();
            builder.append("{");
            for (int key : map.keySet()) {
                builder.append(key)
                        .append(":")
                        .append(map.get(key))
                        .append(",");
            }
            builder.append("}");
            MyLog.e("MyLiveDataViewModel", "已保存的值 = " + builder);
        } else {
            MyLog.e("MyLiveDataViewModel", "空值");
        }
    }
}

代码自己看吧,都开始用LiveData了,就默认都会了。

1)这里的Serializable没什么用,以前使用intent传递数据,序列化用的,复制的时候就继续用了。(ps:以后的新项目应该可以只使用LiveData传递数据,个人认为简单方便)

2)该类仅使用一个map作为变量,从初始化方法可以看出,是连续的数据存储,上方的static数据与其对应

3)DEFAULT变量,这个是自定义的消息阻断标记,后面使用的时候可以看到用法,很好理解

二、初始化ViewModel

private static MutableLiveData<MyLiveDataViewModel> liveData = new MutableLiveData<>();

    public static void putValue(int flag, int type, Object object) {
        MyLiveDataViewModel model = MyApplication.getLiveData().getValue();
        if (model == null) {
            model = new MyLiveDataViewModel(MyLiveDataViewModel.DEFAULT, MyLiveDataViewModel.DEFAULT, null);
        }
        model.putData(flag, type, object);
        getLiveData().postValue(model);
    }

    public static MutableLiveData<MyLiveDataViewModel> getLiveData() {
        if (liveData == null) {
            liveData = new MutableLiveData<>();
        }
        return liveData;
    }

从代码里可以看出,数据都是复用,有个一个好处,就是假设出现了需要同时传递多个数据的情况时,数据不会被覆盖。

三、如何使用

1)如何传值

//MyApplication.putValue(int flag, int type, Object object)
//flag(标记,用户列表),type(类型,刷新列表),object(传值,这里不需要传值)
MyApplication.putValue(MyLiveDataViewModel.userList, MyLiveDataViewModel.userListFresh, null);
User user = new User();
//flag(标记,用户列表),type(类型,执行另外的刷新策略),object(传值,假设这里需要传一个用户,自行替换就行)
MyApplication.putValue(MyLiveDataViewModel.userList, MyLiveDataViewModel.userListFresh2, user);

2)如何接收数据

//该方法需在onCreate里执行
private void initLiveData() {
        MyApplication.getLiveData().observe(this, new Observer<MyLiveDataViewModel>() {
            @Override
            public void onChanged(@Nullable MyLiveDataViewModel viewModel) {
                    if (viewModel != null && viewModel.getType(MyLiveDataViewModel.userList) == MyLiveDataViewModel.userListFresh) { 
                    //执行列表刷新

                    //viewModel的clean方法,将map中flag对应的value修改为DEFAULT,标记为已使用
                    viewModel.clean(MyLiveDataViewModel.userList);
                     
                    //将已使用的数据重新填充回LiveData,此时observe会再次被触发,
                    //但是已被标记为DEFAULT,无事件处理,完成了一次数据传递,
                    //并且其他的消息并未受到影响
                    MyApplication.getLiveData().postValue(viewModel);
                    freshList();
                }else if(viewModel != null && viewModel.getType(MyLiveDataViewModel.userList) == MyLiveDataViewModel.userListFresh2){
                    //执行另外的刷新策略
                    
                    //需要传递Object值时
                    freshData((User)viewModel.getObject());
                    viewModel.clean(MyLiveDataViewModel.userList);
                    MyApplication.getLiveData().postValue(viewModel);
                    }
            }
        });
    }

以上,就是个人最新的LiveData使用,如果大家有更棒的想法,多多分享。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值