-
Notifications
You must be signed in to change notification settings - Fork 629
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
hegaojian
committed
Nov 26, 2020
1 parent
9a0a1a9
commit e109e78
Showing
47 changed files
with
181 additions
and
372 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
135 changes: 6 additions & 129 deletions
135
JetpackMvvm/src/main/java/me/hgj/jetpackmvvm/callback/livedata/event/EventLiveData.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,134 +1,11 @@ | ||
/* | ||
* Copyright 2018-2019 KunMinX | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package me.hgj.jetpackmvvm.callback.livedata.event | ||
|
||
import androidx.lifecycle.LifecycleOwner | ||
import androidx.lifecycle.LiveData | ||
import androidx.lifecycle.MutableLiveData | ||
import androidx.lifecycle.Observer | ||
import java.util.* | ||
import com.kunminx.architecture.ui.callback.UnPeekLiveData | ||
|
||
|
||
/** | ||
* TODO:UnPeekLiveData 的存在是为了在 "重回二级页面" 的场景下,解决 "数据倒灌" 的问题。 | ||
* 对 "数据倒灌" 的状况不理解的小伙伴,可参考《jetpack MVVM 精讲》的解析 | ||
* | ||
* | ||
* https://juejin.im/post/5dafc49b6fb9a04e17209922 | ||
* | ||
* | ||
* 本类参考了官方 SingleEventLive 的非入侵设计, | ||
* | ||
* | ||
* TODO:并创新性地引入了 "延迟清空消息" 的设计, | ||
* 如此可确保: | ||
* 1.一条消息能被多个观察者消费 | ||
* 2.延迟期结束,不再能够收到旧消息的推送 | ||
* 3.并且旧消息在延迟期结束时能从内存中释放,避免内存溢出等问题 | ||
* 4.让非入侵设计成为可能,遵循开闭原则 | ||
* 用于限制从 Activity/Fragment 推送数据,推送数据务必通过唯一可信源来分发, | ||
* 如果这样说还不理解,详见: | ||
* https://xiaozhuanlan.com/topic/6719328450 和 https://xiaozhuanlan.com/topic/0168753249 | ||
* | ||
* | ||
* Create by KunMinX at 19/9/23 | ||
* 最新版的发送消息LiveData使用 https://github.com/KunMinX/UnPeek-LiveData 的最新版,因为跟其他类名(UnPeekLiveData)一致 所以继承换了一个名字 | ||
* 在Activity中observe 调用observeInActivity 在Fragment中使用调用 observeInFragment | ||
* 具体写法请参考 https://github.com/KunMinX/UnPeek-LiveData的示例 | ||
*/ | ||
open class EventLiveData<T> : MutableLiveData<T>() { | ||
private var isCleaning = false | ||
private var hasHandled = true | ||
private var isDelaying = false | ||
protected var DELAY_TO_CLEAR_EVENT = 1000 | ||
private val mTimer = Timer() | ||
private var mTask: TimerTask? = null | ||
protected var isAllowNullValue = false | ||
protected var isAllowToClear = true | ||
override fun observe( | ||
owner: LifecycleOwner, | ||
observer: Observer<in T> | ||
) { | ||
super.observe(owner, Observer { | ||
if (isCleaning) { | ||
hasHandled = true | ||
isDelaying = false | ||
isCleaning = false | ||
return@Observer | ||
} | ||
if (!hasHandled) { | ||
hasHandled = true | ||
isDelaying = true | ||
observer.onChanged(it) | ||
} else if (isDelaying) { | ||
observer.onChanged(it) | ||
} | ||
}) | ||
} | ||
|
||
/** | ||
* UnPeekLiveData 主要用于表现层的 页面转场 和 页面间通信 场景下的非粘性消息分发, | ||
* 出于生命周期安全等因素的考虑,不建议使用 observeForever 方法, | ||
* | ||
* | ||
* 对于数据层的工作,如有需要,可结合实际场景使用 MutableLiveData 或 kotlin flow。 | ||
* | ||
* @param observer | ||
*/ | ||
override fun observeForever(observer: Observer<in T?>) { | ||
throw IllegalArgumentException("Do not use observeForever for communication between pages to avoid lifecycle security issues") | ||
} | ||
|
||
/** | ||
* 重写的 setValue 方法,默认不接收 null | ||
* 可通过 Builder 配置允许接收 | ||
* 可通过 Builder 配置消息延时清理的时间 | ||
* | ||
* | ||
* override setValue, do not receive null by default | ||
* You can configure to allow receiving through Builder | ||
* And also, You can configure the delay time of message clearing through Builder | ||
* | ||
* @param value | ||
*/ | ||
override fun setValue(value: T?) { | ||
if (!isCleaning && !isAllowNullValue && value == null) { | ||
return | ||
} | ||
hasHandled = false | ||
isDelaying = false | ||
super.setValue(value) | ||
if (mTask != null) { | ||
mTask!!.cancel() | ||
mTimer.purge() | ||
} | ||
if (value != null) { | ||
mTask = object : TimerTask() { | ||
override fun run() { | ||
clear() | ||
} | ||
} | ||
mTimer.schedule(mTask, DELAY_TO_CLEAR_EVENT.toLong()) | ||
} | ||
} | ||
|
||
private fun clear() { | ||
if (isAllowToClear) { | ||
isCleaning = true | ||
super.postValue(null) | ||
} else { | ||
hasHandled = true | ||
isDelaying = false | ||
} | ||
} | ||
|
||
} | ||
class EventLiveData<T> : UnPeekLiveData<T>() |
Oops, something went wrong.