Browse Source

发音粘性事件处理,防数据丢失处理,统计显示异常处理

master
suliang 2 years ago
parent
commit
65516356f1

+ 2
- 0
.idea/misc.xml View File

@@ -238,6 +238,8 @@
<entry key="..\:/xuekaole/XKLLocal/app/src/main/res/layout/dictionary_floating_layout.xml" value="0.5" />
<entry key="..\:/xuekaole/XKLLocal/app/src/main/res/layout/fragment_course_pack.xml" value="0.3338541666666667" />
<entry key="..\:/xuekaole/XKLLocal/app/src/main/res/layout/fragment_learn_center.xml" value="0.3338541666666667" />
<entry key="..\:/xuekaole/XKLLocal/app/src/main/res/layout/fragment_statistics_time_top.xml" value="0.23385416666666667" />
<entry key="..\:/xuekaole/XKLLocal/app/src/main/res/layout/item_statics_for_time.xml" value="0.24791666666666667" />
<entry key="..\:/xuekaole/XKLLocal/lib/common/src/main/res/drawable/ic_search.xml" value="0.2212962962962963" />
</map>
</option>

+ 6
- 5
app/src/main/java/com/xkl/cdl/data/repository/AudioCache.kt View File

@@ -1,9 +1,8 @@
package com.xkl.cdl.data.repository

import android.net.IpPrefix
import android.util.LruCache
import androidx.lifecycle.MutableLiveData
import com.suliang.common.AppConfig
import com.suliang.common.eventbus.SingleLiveData
import com.suliang.common.extension.diskIo2Main
import com.suliang.common.util.file.FileUtil
import com.xkl.cdl.data.AppConstants
@@ -33,10 +32,12 @@ object AudioCache {
}
/** 通知查到的录音 */
private lateinit var audioLiveData : MutableLiveData<String?>
private lateinit var audioLiveData : SingleLiveData<String?>
fun initAudioLiveData() : MutableLiveData<String?> {
audioLiveData = MutableLiveData<String?>()
fun initAudioLiveData() : SingleLiveData<String?> {
if (!this::audioLiveData.isInitialized){
audioLiveData = SingleLiveData<String?>()
}
return audioLiveData
}

+ 12
- 11
app/src/main/java/com/xkl/cdl/module/XKLApplication.kt View File

@@ -3,6 +3,7 @@ package com.xkl.cdl.module
import android.app.Activity
import android.app.Application
import android.os.Bundle
import com.suliang.common.base.LibApplication
import com.suliang.common.util.ActivityStackManager
import com.suliang.common.util.LogUtil
import com.suliang.common.util.file.FileUtil
@@ -25,34 +26,34 @@ import kotlin.properties.Delegates
* create 2022/3/14 11:27
* Describe:
*/
class XKLApplication : Application() {
class XKLApplication : LibApplication() {
companion object{
val mobileCache:MobileCache by lazy {
val file : String = File(FileUtil.getSaveDirFile("db"), "mydb").absolutePath
Mobile_cache.new_(file)
}
private var instance : XKLApplication by Delegates.notNull()
fun instance() = instance
// private var instance : XKLApplication by Delegates.notNull()
fun instance() = LibApplication.instance()
}
override fun onCreate() {
super.onCreate()
instance = this
// instance = this
SQLiteDatabase.loadLibs(this)
LogUtil.e(UUID.randomUUID().toString().replace("-",""))
// LogUtil.e(UUID.randomUUID().toString().replace("-",""))
//初始MMKV存储
val rootDir = MMKV.initialize(this)
LogUtil.e(rootDir)
setRxJavaErrorHandler()
// val rootDir = MMKV.initialize(this)
// LogUtil.e(rootDir)
// setRxJavaErrorHandler()
// HookMobileCache().hook()
// registerActivityLifecycleCallbacks(lifecycleCallback)
}
/***
/* *//***
* 避免 调用多次onError。正常来说第一次onError会走正常的Observer处理,其他会走ErrorHandler。通过此方法捕捉多次的error
*/
*//*
private fun setRxJavaErrorHandler(){
RxJavaPlugins.setErrorHandler(Consumer { e ->
e.printStackTrace()
@@ -78,7 +79,7 @@ class XKLApplication : Application() {
})
}
*/
private object lifecycleCallback : Application.ActivityLifecycleCallbacks {
private var count = 0

+ 14
- 10
app/src/main/java/com/xkl/cdl/module/m_statics/StatisticsTimeTopFragment.kt View File

@@ -44,22 +44,26 @@ class StatisticsTimeTopFragment : BaseFragmentVM<FragmentStatisticsTimeTopBindin
//监听时间选项变化
vm.timeStatisticsPositionLiveData.observe(this) { position ->
if (!vm.isInitStatisticsResponse()) {
vm.getStatistics().observe(this) {
if (it) {
(binding.rvTime.adapter as AdapterStaticsTime).setData(vm.timeValuesList[position])
}
}
} else {
// if (!vm.isInitStatisticsResponse()) {
// vm.getStatistics().observe(this) {
// if (it) {
// (binding.rvTime.adapter as AdapterStaticsTime).setData(vm.timeValuesList[position])
// }
// }
// } else {
(binding.rvTime.adapter as AdapterStaticsTime).setData(vm.timeValuesList[position])
}
// }
}
}
override fun loadData() {
//设置选中加载数据
vm.timeStatisticsPositionLiveData.value = binding.tabLayoutTime.selectedTabPosition
// vm.timeStatisticsPositionLiveData.value = binding.tabLayoutTime.selectedTabPosition
vm.getStatistics().observe(this) {
if (it) {
(binding.rvTime.adapter as AdapterStaticsTime).setData(vm.timeValuesList[binding.tabLayoutTime.selectedTabPosition])
}
}
}
private fun initTabLayout() {

+ 129
- 16
app/src/main/java/com/xkl/cdl/module/m_statics/StatisticsTimeTopFragmentViewModel.kt View File

@@ -55,7 +55,11 @@ open class StatisticsTimeTopFragmentViewModel : BaseViewModel() {
protected fun initTimeStaticItem(statistics : AppApi.Statistics) : MutableList<TimeStatisticItem> {
val result = mutableListOf<TimeStatisticItem>()
//有效学习时长
result.add(initValideTime(statistics)) //添加有效学习时常
result.add(initEfficiency(statistics)) //效率
result.add(initCourseCount(statistics)) //课程
result.add(initLearnProgress(statistics)) //已学进度
/* //有效学习时长
val timeStaticItem_1 = TimeStatisticItem().apply {
name = "有效学习时长"
backGround = R.drawable.shape_rounder_4_red_a5
@@ -83,9 +87,10 @@ open class StatisticsTimeTopFragmentViewModel : BaseViewModel() {
}
}
}else{
timeStaticItem_1.time = "0"
timeStaticItem_1.unit = ""
timeStaticItem_1.time = ""
timeStaticItem_1.unit = "不足1分钟"
}
initIncr(timeStaticItem_1,statistics.sdIncr.toDouble())
//增量不为0
if (statistics.sdIncr != 0L ){
val hour_1 = statistics.sdIncr / 3600000.0
@@ -99,11 +104,15 @@ open class StatisticsTimeTopFragmentViewModel : BaseViewModel() {
//小于1分钟 秒数
else -> timeStaticItem_1.incr = "${sencond}秒"
}
if (statistics.sdIncr > 0){
timeStaticItem_1.incr = "+${timeStaticItem_1.incr}"
}
}else{
timeStaticItem_1.incr = ""
}
initIncr(timeStaticItem_1,statistics.sdIncr.toDouble())
result.add(timeStaticItem_1)
result.add(timeStaticItem_1)*/
//综合学习效率
/* //综合学习效率
val timeStaticItem_2 = TimeStatisticItem().apply {
backGround = R.drawable.shape_rounder_4_theme_a5
name = "综合学习效率"
@@ -131,20 +140,128 @@ open class StatisticsTimeTopFragmentViewModel : BaseViewModel() {
time = initShow(statistics.ts)
initIncr(this,statistics.tsIncr)
}
result.add(timeStaticItem_4)
result.add(timeStaticItem_4)*/
return result
}
private fun initValideTime(statistics : AppApi.Statistics) : TimeStatisticItem {
val result = TimeStatisticItem().apply {
name = "有效学习时长"
backGround = R.drawable.shape_rounder_4_red_a5
//时长显示
if (statistics.sd != 0L) {
val hour = statistics.sd / 3600000.0
val minute = statistics.sd / 60000.0
when {
//大于1小时
hour > 1 -> {
time =initShow(hour)
unit = "小时"
}
//大于1分钟
minute > 1 -> {
//取整和保留一位小数的值相同,则使用取整的值显示,否则使用保留小数的值显示
time =initShow(minute)
unit = "分钟"
}
//小于1分钟
else -> {
time = ""
unit = "不足1分钟"
}
}
}else{
time = ""
unit = "不足1分钟"
}
//增量处理
incr = if (statistics.sdIncr != 0L ) {
val hour_1 = statistics.sdIncr / 3600000.0
val minute_1 = statistics.sdIncr / 60000.0
val sencond = statistics.sdIncr / 1000
val temp : String = when {
//大于1小时
abs(hour_1) > 1 -> if(statistics.sdIncr > 0) "${initShow(hour_1)}小时" else "-${initShow(abs(hour_1))}小时"
//大于1分钟
abs(minute_1) > 1 ->if(statistics.sdIncr > 0) "${initShow(minute_1)}分钟" else "-${initShow(abs(minute_1))}分钟"
//小于1分钟 秒数
else -> "${sencond}秒"
}
if (statistics.sdIncr > 0){
"+${temp}"
} else temp
} else ""
//增量颜色和箭头处理
initIncr(this,statistics.sdIncr.toDouble())
}
return result
}
private fun initEfficiency(statistics : AppApi.Statistics) : TimeStatisticItem {
val result = TimeStatisticItem().apply {
backGround = R.drawable.shape_rounder_4_theme_a5
name = "综合学习效率"
unit = "%"
time = initShow(statistics.se)
initIncr(this,statistics.seIncr)
//增量
incr = when {
statistics.seIncr == 0.0 -> ""
statistics.seIncr > 0 -> "+${initShow(statistics.seIncr)}$unit"
else -> "${initShow(statistics.seIncr)}$unit"
}
}
return result
}
private fun initCourseCount(statistics : AppApi.Statistics) : TimeStatisticItem {
val result = TimeStatisticItem().apply {
backGround = R.drawable.shape_rounder_4_green_a5
name = "已学课程"
unit = "/${CourseManager.getTotalCourseSize()}个"
time = "${statistics.sc}"
initIncr(this,statistics.scIncr.toDouble())
//增量
incr = when {
statistics.scIncr == 0L -> ""
statistics.scIncr > 0 -> "+${statistics.scIncr}"
else -> "${statistics.scIncr}"
}
}
return result
}
private fun initLearnProgress(statistics : AppApi.Statistics) : TimeStatisticItem {
val result = TimeStatisticItem().apply {
backGround = R.drawable.shape_rounder_4_purple_a5
name = "已学进度"
unit = "%"
time = initShow(statistics.ts)
initIncr(this,statistics.tsIncr)
//增量
incr = when {
statistics.tsIncr == 0.0 -> ""
statistics.tsIncr > 0 -> "+${initShow(statistics.tsIncr)}$unit"
else -> "${initShow(statistics.tsIncr)}$unit"
}
}
return result
}

/** 格式化数据,决定显示小数还是不显示 */
private fun initShow(value:Double):String{
val temp = abs(value)
//保留一位小数 向下取舍
val formatFloor = NumberUtils.formatFloor(value, "0.0")
val formatFloor = NumberUtils.formatFloor(temp, "0.0")
val toDouble = formatFloor.toDouble()
//取整
val formatFloor_1 = NumberUtils.formatFloor(value, "0")
val toDouble_1 = formatFloor.toDouble()
val formatFloor_1 = NumberUtils.formatFloor(temp, "0")
val toDouble_1 = formatFloor_1.toDouble()
//取整和保留一位小数的值相同,则使用取整的值显示,否则使用保留小数的值显示
return when (toDouble_1) {
return (if (value < 0 ) "-" else "") + when (toDouble_1) {
toDouble -> formatFloor_1
else -> formatFloor
}
@@ -154,14 +271,10 @@ open class StatisticsTimeTopFragmentViewModel : BaseViewModel() {
private fun initIncr(timeStaticItem_1 : TimeStatisticItem, sdIncr : Double) {
timeStaticItem_1.run {
when{
sdIncr == 0.0 -> {
incr = ""
imgDrawable = R.drawable.ic_keep
}
sdIncr == 0.0 -> imgDrawable = R.drawable.ic_keep
sdIncr > 0 -> {
imgDrawable = R.drawable.ic_rise
incrTextColor = R.color.green_1
incr = "+$incr"
}
else -> {
imgDrawable = R.drawable.ic_decline

+ 6
- 1
app/src/main/java/com/xkl/cdl/module/main/MainActivity.kt View File

@@ -18,6 +18,7 @@ import com.xkl.cdl.module.m_memo.MemoFragment
import com.xkl.cdl.module.m_my.MyFragment
import com.xkl.cdl.module.m_service_center.ServiceCenterFragment
import com.xkl.cdl.module.m_statics.StaticsFragment
import com.xkl.cdl.module.splash.SplashActivity
import com.zackratos.ultimatebarx.ultimatebarx.java.UltimateBarX
import com.zackratos.ultimatebarx.ultimatebarx.statusBarOnly

@@ -41,7 +42,11 @@ class MainActivity : BaseActivityVM<ActivityMainBinding, MainActivityViewModel>(
override fun initViewModel(): MainActivityViewModel {
return ViewModelProvider(this)[MainActivityViewModel::class.java]
}

override fun protectApp() {
startActivity(SplashActivity::class.java)
finish()
}

override fun initActivity(savedInstanceState: Bundle?) {
//点击事件

+ 3
- 2
app/src/main/java/com/xkl/cdl/module/splash/SplashActivity.kt View File

@@ -25,12 +25,13 @@ import java.util.concurrent.TimeUnit
@SuppressLint("CustomSplashScreen")
class SplashActivity : BaseActivity<ActivitySplashBinding>() {
override fun onCreate(savedInstanceState : Bundle?) {
override fun onCreateOwn(savedInstanceState : Bundle?) {
if (!isTaskRoot) {
finish()
return
}
super.onCreate(savedInstanceState)
XKLApplication.instance().isLaunch = true
super.onCreateOwn(savedInstanceState)
}
override fun initActivity(savedInstanceState : Bundle?) {

+ 66
- 0
lib/common/src/main/java/com/suliang/common/base/LibApplication.kt View File

@@ -0,0 +1,66 @@
package com.suliang.common.base

import android.app.Application
import android.database.sqlite.SQLiteDatabase
import com.suliang.common.util.LogUtil
import com.tencent.mmkv.MMKV
import io.reactivex.rxjava3.exceptions.UndeliverableException
import io.reactivex.rxjava3.functions.Consumer
import io.reactivex.rxjava3.plugins.RxJavaPlugins
import java.io.IOException
import java.util.*
import kotlin.properties.Delegates

/**
* @Author: suliang
* @create: 2022/8/23 11:07
* @Description:
*/
open class LibApplication : Application(){
//是否启动标记,用于避免应用重启时的问题
var isLaunch = false
companion object {
protected var instance : LibApplication by Delegates.notNull()
@JvmStatic
fun instance() = instance
}
override fun onCreate() {
super.onCreate()
instance = this
//初始MMKV存储
val rootDir = MMKV.initialize(this)
LogUtil.e(rootDir)
setRxJavaErrorHandler()
// HookMobileCache().hook()
// registerActivityLifecycleCallbacks(lifecycleCallback)
}
/***
* 避免 调用多次onError。正常来说第一次onError会走正常的Observer处理,其他会走ErrorHandler。通过此方法捕捉多次的error
*/
private fun setRxJavaErrorHandler(){
RxJavaPlugins.setErrorHandler(Consumer { e ->
e.printStackTrace()
LogUtil.e( "RxJavaErrorHandler --> \n $e")
if (e is UndeliverableException) {
return@Consumer
} else if (e is IOException) {
// fine, irrelevant network problem or API that throws on cancellation
return@Consumer
} else if (e is InterruptedException) {
// fine, some blocking code was interrupted by a dispose call
return@Consumer
} else if (e is NullPointerException || e is IllegalArgumentException) {
// that's likely a bug in the application
Thread.currentThread().uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), e)
return@Consumer
} else if (e is IllegalStateException) {
// that's a bug in RxJava or in a custom operator
Thread.currentThread().uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), e)
return@Consumer
}
LogUtil.e( "RxJavaErrorHandler --> unknown exception = \n $e")
})
}
}

+ 30
- 7
lib/common/src/main/java/com/suliang/common/base/activity/UIBaseActivity.kt View File

@@ -1,10 +1,12 @@
package com.suliang.common.base.activity

import android.content.ComponentName
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.widget.Toast
import androidx.annotation.StringRes
import com.suliang.common.base.LibApplication
import com.suliang.common.base.LoadingDialog
import com.suliang.common.base.ViewBehavior
import com.suliang.common.util.ActivityStackManager
@@ -20,6 +22,14 @@ abstract class UIBaseActivity : LifecycleLogActivity(), ViewBehavior {
override fun onCreate(savedInstanceState : Bundle?) {
super.onCreate(savedInstanceState)
onCreateOwn(savedInstanceState)
}
protected open fun onCreateOwn(savedInstanceState : Bundle?) {
if (!LibApplication.instance().isLaunch) {
protectApp()
return
}
//入栈
ActivityStackManager.addActivity(this)
initFirst()
@@ -27,6 +37,21 @@ abstract class UIBaseActivity : LifecycleLogActivity(), ViewBehavior {
loadData()
}
/**
* 当Application启动的时候, LibApplication的isLaunch为false
* 在SplashActivity启动的时候改变该值为true
* 当为true时,app回到前台,即 应用没有重启
* 当为false时,即应用重启了
*/
protected open fun protectApp() {
startActivity(Intent().apply {
component = ComponentName(applicationContext, "com.xkl.cdl.module.main.MainActivity")
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) //清空栈里MainActivity之上的所有Activity
})
finish()
}
/***
* 实例化binding,
*/
@@ -86,10 +111,9 @@ abstract class UIBaseActivity : LifecycleLogActivity(), ViewBehavior {
val showTime = if (event.showLong) Toast.LENGTH_LONG else Toast.LENGTH_LONG
event.content?.let {
Toast.makeText(this, it, showTime).show()
} ?: let {
Toast.makeText(this, event.contentResId!!, showTime).show()
}
?: let {
Toast.makeText(this, event.contentResId!!, showTime).show()
}
}
protected fun showToast(text : String, showLong : Boolean = false) {
@@ -108,11 +132,10 @@ abstract class UIBaseActivity : LifecycleLogActivity(), ViewBehavior {
if (findFragment is LoadingDialog) {
findFragment.dialog?.show()
}
} ?: let {
val loadingDialog = LoadingDialog.newInstance("")
loadingDialog.show(supportFragmentManager, "loading")
}
?: let {
val loadingDialog = LoadingDialog.newInstance("")
loadingDialog.show(supportFragmentManager, "loading")
}
} else { //关闭
findFragment?.let {
if (it is LoadingDialog) {

+ 1
- 1
lib/common/src/main/java/com/suliang/common/eventbus/LiveDataBus.kt View File

@@ -40,7 +40,7 @@ object LiveDataBus {
if (isSticky){
bus[key] = MutableLiveData()
}else{
bus[key] = NonStickyMutableLivedata()
bus[key] = SingleLiveData()
}
}
return bus[key] as MutableLiveData<T>

+ 0
- 81
lib/common/src/main/java/com/suliang/common/eventbus/NonStickyMutableLivedata.kt View File

@@ -1,81 +0,0 @@
package com.suliang.common.eventbus

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import java.lang.Exception
import java.lang.NullPointerException
import java.lang.reflect.Method

/**
* author suliang
* create 2022/3/15 10:51
* Describe: 非粘性LiveData ,需要先设置监听再发送数据,即后注册的监听收不到以前的监听
* 事件总线的LiveData 非粘性事件传false(刚注册时如果有事件则不发送) 粘性事件传true
* @param isSticky false非粘性事件 true粘性事件
*/
internal class NonStickyMutableLivedata<T> : MutableLiveData<T>() {
// override fun observe(owner : LifecycleOwner, observer : Observer<in T>) {
// super.observe(owner, ObserverWrapper<T>(observer))
// }
//
// class ObserverWrapper<T>(var observer:Observer<in T>) : Observer<T> {
// var isSticky = false
// override fun onChanged(t : T) {
// if (isSticky){
// observer.onChanged(t)
// }else{
// isSticky = true
// }
// }
// }
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, observer)
hook(observer)
}
override fun removeObserver(observer : Observer<in T>) {
super.removeObserver(observer)
}
private fun hook(observer : Observer<in T>) = try {
//得到 mLastVersion
//获取到LiveData的类中的mObserver对象
// SafeIterableMap<Observer<? super T> , ObserverWrapper> mObservers
val liveDataClass = LiveData::class.java
val declaredField = liveDataClass.getDeclaredField("mObservers")
declaredField.isAccessible = true
//获取到这个成员变量的对象
val mObserVersObject = declaredField.get(this)
//得到map对应的class对象
val mObserversClass = mObserVersObject.javaClass
//获取到mObservers对象的get方法
val get : Method = mObserversClass.getDeclaredMethod("get", Any::class.java)
get.isAccessible = true
//执行get方法,获取到对象
val invokeEntry = get.invoke(mObserVersObject, observer)
//定义一个空的对象
val observerWrapper = if (invokeEntry is Map.Entry<*, *>) {
invokeEntry.value
} else throw NullPointerException("observerWrapper is null")
//得到observerWrapper的对象,编译擦除问题会引起多态冲突,所以用getSupperClass
//getClass 返回对应的当前正在运行是的类所对应的
val mLastVersion = observerWrapper!!::class.java.superclass.getDeclaredField("mLastVersion")
mLastVersion.isAccessible = true
//得到mVersion
val mVersion = liveDataClass.getDeclaredField("mVersion")
mVersion.isAccessible = true
//把mVersion数据填入到mLastVersion中
val mVersionValue = mVersion.get(this)
mLastVersion.set(observerWrapper, mVersionValue)
} catch (e : Exception) {
e.printStackTrace()
}
}

+ 97
- 0
lib/common/src/main/java/com/suliang/common/eventbus/SingleLiveData.kt View File

@@ -0,0 +1,97 @@
package com.suliang.common.eventbus

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import java.lang.Exception
import java.lang.NullPointerException
import java.lang.reflect.Method
import java.util.concurrent.atomic.AtomicBoolean

/**
* author suliang
* create 2022/3/15 10:51
* Describe: https://blog.csdn.net/bzb123321/article/details/98210342
*/
class SingleLiveData<T> : MutableLiveData<T>() {
/*非粘性LiveData ,需要先设置监听再发送数据,即后注册的监听收不到以前的监听
* 事件总线的LiveData 非粘性事件传false(刚注册时如果有事件则不发送) 粘性事件传true
* @param isSticky false非粘性事件 true粘性事件*/
// override fun observe(owner : LifecycleOwner, observer : Observer<in T>) {
// super.observe(owner, ObserverWrapper<T>(observer))
// }
//
// class ObserverWrapper<T>(var observer:Observer<in T>) : Observer<T> {
// var isSticky = false
// override fun onChanged(t : T) {
// if (isSticky){
// observer.onChanged(t)
// }else{
// isSticky = true
// }
// }
// }
companion object{
private val mPending : AtomicBoolean = AtomicBoolean(false)
}
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
super.observe(owner, Observer {
if (mPending.compareAndSet(true,false)){
observer.onChanged(it)
}
})
// hook(observer)
}
override fun setValue(value : T?) {
mPending.set(true)
super.setValue(value)
}
public fun call(){
setValue(null)
}
// override fun removeObserver(observer : Observer<in T>) {
// super.removeObserver(observer)
// }
// private fun hook(observer : Observer<in T>) = try {
// //得到 mLastVersion
// //获取到LiveData的类中的mObserver对象
// // SafeIterableMap<Observer<? super T> , ObserverWrapper> mObservers
// val liveDataClass = LiveData::class.java
// val declaredField = liveDataClass.getDeclaredField("mObservers")
// declaredField.isAccessible = true
// //获取到这个成员变量的对象
// val mObserVersObject = declaredField.get(this)
// //得到map对应的class对象
// val mObserversClass = mObserVersObject.javaClass
// //获取到mObservers对象的get方法
// val get : Method = mObserversClass.getDeclaredMethod("get", Any::class.java)
// get.isAccessible = true
// //执行get方法,获取到对象
// val invokeEntry = get.invoke(mObserVersObject, observer)
// //定义一个空的对象
// val observerWrapper = if (invokeEntry is Map.Entry<*, *>) {
// invokeEntry.value
// } else throw NullPointerException("observerWrapper is null")
//
// //得到observerWrapper的对象,编译擦除问题会引起多态冲突,所以用getSupperClass
// //getClass 返回对应的当前正在运行是的类所对应的
// val mLastVersion = observerWrapper!!::class.java.superclass.getDeclaredField("mLastVersion")
// mLastVersion.isAccessible = true
// //得到mVersion
// val mVersion = liveDataClass.getDeclaredField("mVersion")
// mVersion.isAccessible = true
// //把mVersion数据填入到mLastVersion中
// val mVersionValue = mVersion.get(this)
// mLastVersion.set(observerWrapper, mVersionValue)
//
// } catch (e : Exception) {
// e.printStackTrace()
// }
}

Loading…
Cancel
Save