LiveData其实就是通过管理生命周期来实现当视图不可见时不渲染数据,当视图可见时再渲染数据.当在一个Activity发送一个网络请求后,立马切到另一个界面或都按下Home键,使得视图不可见..这个时候网络请求还在进行,当网络请求完成后,会判断这个界面是活跃状态还是不活跃状态,如果是不活跃状态则把数据保存在一个缓存集合里面,当这个视图可见时,就会回调其onStart方法,这里我们就可以监听到,然后将缓存数据显示到界面..

那么自己也写一个

创建一个生命周期接口

public interface Lifecycle {void onCreate(int activityCode);void onStart(int activityCode);void onStop(int activityCode);void onPause(int activityCode);void onDetach(int activityCode);
}

创建一个自己的LiveData类并实现Lifecycle

public class LiveData<T> implements Lifecycle {
}

监听事件,我们肯定需要一个观察者,创建一个

public abstract class Observer<T> {//活跃状态  可能收到消息static final int STATE_ACTIVE = 1;//暂停状态,不能收到消息static final int STATE_ONPAUSE = 2;//销毁状态static final int STATE_ONDESTORY = 3;//初始化状态static final int STATE_ONINIT = 0;private int state = STATE_ONINIT;public int getState() {return state;}public void setState(int state) {this.state = state;}public abstract void onChanged(T t);}

我们LiveData肯定要管理所有注册的观察者,所以里面肯定有个管理集合,还要提供一个注册的方法

//  Integer是我们Activity的hashcode值
private Map<Integer, Observer<T>> observers = new HashMap<>();//进行注册
public void observe(FragmentActivity activity, Observer<T> observer) {observers.put(activity.hashCode(), observer);
}

最后就是要设置值来达到显示数据的作用

public void setValue(T value) {for (Map.Entry<Integer, Observer<T>> entry : observers.entrySet()) {Observer<T> observer = entry.getValue();Integer activityCode = entry.getKey();observer.onChanged(value);}

这样所有注册了的观察都就都能收到数据.

现在来完成怎样管理生命周期

一般管理生命周期都是一个道理,用一个没有界面的fragment来完成,我们这也一样创建一个LifeFragment

public class LifeFragment extends Fragment {private Lifecycle mLifecycle;private int activityCode;public void setLifecycle(Lifecycle lifecycle){this.mLifecycle = lifecycle;}@Overridepublic void onAttach(Activity activity) {super.onAttach(activity);activityCode = activity.hashCode();if (mLifecycle != null) {mLifecycle.onCreate(activityCode);}}@Overridepublic void onDetach() {super.onDetach();if (mLifecycle != null) {mLifecycle.onDetach(activityCode);}}@Overridepublic void onPause() {super.onPause();if (mLifecycle != null) {mLifecycle.onPause(activityCode);}}@Overridepublic void onStop() {super.onStop();if (mLifecycle != null) {mLifecycle.onStop(activityCode);}}@Overridepublic void onStart() {super.onStart();if (mLifecycle != null) {mLifecycle.onStart(activityCode);}}
}

然后回来我们LiveData类里面的注册方法里面,应该添加创建LifeFragment方法并设置监听

public void observe(FragmentActivity activity, Observer<T> observer) {FragmentManager fm = activity.getSupportFragmentManager();observers.put(activity.hashCode(), observer);LifeFragment fragment = (LifeFragment) fm.findFragmentByTag("luckly.ancely.com.commonentmodule");if (fragment == null) {fragment = new LifeFragment();fm.beginTransaction().add(fragment, "luckly.ancely.com.commonentmodule").commitAllowingStateLoss();}fragment.setLifecycle(this);
}

这样我们就可以管理我们Actiity的生命周期了.这样就可以在不同的生命周期里面设置数据状态,如下

    @Overridepublic void onCreate(int activityCode) {observers.get(activityCode).setState(Observer.STATE_ONINIT);}@Overridepublic void onStart(int activityCode) {observers.get(activityCode).setState(Observer.STATE_ACTIVE);}@Overridepublic void onStop(int activityCode) {observers.get(activityCode).setState(Observer.STATE_ONPAUSE);}@Overridepublic void onPause(int activityCode) {observers.get(activityCode).setState(Observer.STATE_ONPAUSE);}@Overridepublic void onDetach(int activityCode) {observers.remove(activityCode);}

然后在setValue方法里也要对不同的状态进行不一样的判断 完整代码如下

    public void setValue(T value) {List<Observer> destory = new ArrayList<>();for (Map.Entry<Integer, Observer<T>> entry : observers.entrySet()) {Observer<T> observer = entry.getValue();Integer activityCode = entry.getKey();if (observer.getState() == Observer.STATE_ACTIVE) {//如果是活跃状态,直接设置observer.onChanged(value);}//如果是不活跃状态,则把数据添加到缓存集合里if (observer.getState() == Observer.STATE_ONPAUSE) {if (cacheValue.get(activityCode) == null) {cacheValue.put(activityCode,new ArrayList<T>());}if (!cacheValue.get(activityCode).contains(value)) {cacheValue.get(activityCode).add(value);}}//如果界面已经销毁了,则把其添加到销毁集合里,因为这是在遍历map集合,如果不能直接删除if (observer.getState() == Observer.STATE_ONDESTORY) {destory.add(observer);}}for (Observer observer : destory) {//最后把destory数据消除observers.remove(observer);}}

最后在我们的onStart回调里面设置数据

    @Overridepublic void onStart(int activityCode) {observers.get(activityCode).setState(Observer.STATE_ACTIVE);if (cacheValue.get(activityCode) == null||cacheValue.get(activityCode).size()==0) {return;}for (T t : cacheValue.get(activityCode)) {observers.get(activityCode).onChanged(t);}cacheValue.clear();}

这样我们自己的LiveData就全部实现了.贴一个LiveData全部代码

package luckly.ancely.com.commoentmodule.event;import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class LiveData<T> implements Lifecycle {//Integer activity地址private Map<Integer, Observer<T>> observers = new HashMap<>();private Map<Integer, List<T>> cacheValue = new HashMap<>();public void observe(FragmentActivity activity, Observer<T> observer) {FragmentManager fm = activity.getSupportFragmentManager();observers.put(activity.hashCode(), observer);LifeFragment fragment = (LifeFragment) fm.findFragmentByTag("luckly.ancely.com.commonentmodule");if (fragment == null) {fragment = new LifeFragment();fm.beginTransaction().add(fragment, "luckly.ancely.com.commonentmodule").commitAllowingStateLoss();}fragment.setLifecycle(this);}public void setValue(T value) {List<Observer> destory = new ArrayList<>();for (Map.Entry<Integer, Observer<T>> entry : observers.entrySet()) {Observer<T> observer = entry.getValue();Integer activityCode = entry.getKey();if (observer.getState() == Observer.STATE_ACTIVE) {observer.onChanged(value);}if (observer.getState() == Observer.STATE_ONPAUSE) {if (cacheValue.get(activityCode) == null) {cacheValue.put(activityCode,new ArrayList<T>());}if (!cacheValue.get(activityCode).contains(value)) {cacheValue.get(activityCode).add(value);}}if (observer.getState() == Observer.STATE_ONDESTORY) {destory.add(observer);}}for (Observer observer : destory) {observers.remove(observer);}}@Overridepublic void onCreate(int activityCode) {observers.get(activityCode).setState(Observer.STATE_ONINIT);}@Overridepublic void onStart(int activityCode) {observers.get(activityCode).setState(Observer.STATE_ACTIVE);if (cacheValue.get(activityCode) == null||cacheValue.get(activityCode).size()==0) {return;}for (T t : cacheValue.get(activityCode)) {observers.get(activityCode).onChanged(t);}cacheValue.clear();}@Overridepublic void onStop(int activityCode) {observers.get(activityCode).setState(Observer.STATE_ONPAUSE);}@Overridepublic void onPause(int activityCode) {observers.get(activityCode).setState(Observer.STATE_ONPAUSE);}@Overridepublic void onDetach(int activityCode) {observers.remove(activityCode);cacheValue.clear();}
}

Android livedata原理解析之自己实现一个简单的LiveData相关推荐

  1. 爱加密Android APk 原理解析

    转载请标明出处:http://blog.csdn.net/u011546655/article/details/45921025 爱加密Android APK加壳原理解析 一.什么是加壳? 加壳是在二 ...

  2. LiveData原理解析

    什么是LiveData LiveData是Android Architecture Components 其中的一个组件.主要用于更新UI数据和组件之间传值. 1.LiveData是一种持有可被观察数 ...

  3. 深入了解Vue 2响应式原理,并手写一个简单的Vue

    1. Vue 2的响应式原理 Vue.js 一个核心思想是数据驱动.所谓数据驱动是指视图是由数据驱动生成的,对视图的修改,不会直接操作 DOM,而是通过修改数据.vue.js里面只需要改变数据,Vue ...

  4. Android UI开发: 横向ListView(HorizontalListView)及一个简单相册的完整实现 (附源码下载)

    本文内容: 1.横向ListView的所有实现思路; 2.其中一个最通用的思路HorizontalListView,并基于横向ListView开发一个简单的相册: 3.实现的横向ListView在点击 ...

  5. Android—Gson原理解析

    JsonElement 抽象类 代表json串的某一个元素 某一个元素: JsonObject JsonArray JsonPrimitive(基本类型) JsonNull JsonElement的四 ...

  6. android asynctask,Android AsyncTask原理解析

    想要启动一个AsyncTask,首先需要创建一个AsyncTask对象然后调用execute方法.例如: new DownloadFilesTask().execute(); DownloadFile ...

  7. [Android开发] Json解析工具类,一个类搞定Json的解析

    一.简介 利用递归的方式反射解析到bean里面 二.详细代码 1. Json格式 例如服务器指定规定json格式为: {"code": "--" , // 返回 ...

  8. BAT大量裁人,快35岁的程序员该何去何从,Android并发原理解析

    行业前景 首先我给大家分析一下,现在行业的一个情况. 2018年IT界规模最大的裁员事件了.近日,面对难看的财务报表,美国最大的通讯运营商.市值2200亿美金的Verizon,遣散了4.4万名老员工. ...

  9. Android 6.0 7.0 8.0 一个简单的app内更新版本-okgo app版本更新

    登陆时splash初始页调用接口检查app版本.如有更新,使用okGo的文件下载,保存到指定位置,调用Android安装apk. <!-- Android 8.0 (Android O)为了针对 ...

最新文章

  1. mysql链接数据库properties_mysql 之通过配置文件链接数据库
  2. 旅游O2O“三国杀”竞技:携程系「守」、飞猪「望」、美团「攻」
  3. PHP网站使用JavaScript和Iframe简单实现部分刷新效果
  4. 利用ipsec配置tcp/ip用于安全连接
  5. 《经济学人》新一期封面主题:Govcoins 改变金融的数字货币
  6. 使用jfreechart在jsp页面柱状图统计
  7. keras中的EarlyStopping
  8. wordpress后台加载速度异常缓慢排查记录(原创)
  9. 设计思想之高内聚低耦合
  10. 【无人机控制】四旋翼飞行器飞行控制系统含Matlab源码
  11. ansys时间步长怎么设置_ANSYS瞬态动力学分析中的时间步长的选择
  12. 长截图或长图片如何按页面切分后打印或插入到Word文档中
  13. 色彩三原色,RGB,CMYK
  14. P3840蜗牛一期--虚拟局域网VLAN
  15. math_数集(数集符号)/算数运算中英文对照
  16. 提供 Android 酷炫的开屏动画 (awesome-opening-animation)
  17. 【阅读笔记】Mutual CRF-GNN for Few-shot Learning
  18. linux系统etc什么意思,请问linux下的etc是什么意思?
  19. ChatGPT微信小程序搭建总结
  20. Hive任务执行报错:FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask

热门文章

  1. JointJS实现节点自动布局
  2. Scrapy从入门到精通(3)--使用Item封装数据
  3. 【paper笔记】ESAM: Discriminative Domain Adaptation with Non-Displayed Items to Improve Long-Tail
  4. MTA网络基础考试准备指南
  5. ION内存管理器介绍
  6. GAMIT 分步进行基线解算流程
  7. Vue中的 key 的作用是什么?
  8. markdown编辑器自学+使用说明
  9. pyqt5 同时显示多个画面_体育赛事直播应用NHL.TV可让屏幕同时显示6个画面,全景观看比赛...
  10. 探秘李逵-全球顶级电竞俱乐部