LiveData不走回调

新项目使用的LiveData这个框架,有一天发现LiveData注册的监听回调,永远只走一次,后面的都不走了,这个很奇怪。于是去查找原因。最后发现是try catch引起的。

示例代码:

我的代码大概如下所示:方法中使用了try catch  来防止奔溃

    val mBanner=MutableLiveData<List<Banner>>()
    fun test(){
        println("1")
        try {
            mBanner.observe(this){
                println("2")
                throw  RuntimeException("奔溃了")
                println("3")
            } 
        }catch (e:Exception){
            
        }
        println("4")
    }

//打印的结果: 1,2,4

debug后发现只要第一次奔溃后,后面永远都不会走这个回调。所以说因为bug肯定和tyr catch有关。

我们查看LiveData中分发事件的方法。并且debug在如下标记的位置,发现mDispatchingValue一直是true,导致执行不了下一步。而且mDispatchingValue是一个全局变量。那么这个值在哪里置为false呢?如下方法中标记所示,只有在整个方法执行完才会置为false

 void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {   //在此处debug
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue()); //分发事件
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;  //方法执行完毕后置为falses
    }

所以现在问题就很明确了,就是因为调用方法的 时候奔溃了,导致直接走了catch,后面的代码没有执行完,从而导致dispatchingValue 方法没有执行到底,mDispatchingValue就一直为 true了。

解决方法:

那么如何实现即避免奔溃,同时能走回调呢?

我们在注册回调奔溃的地方再用try catch包住,这样就能完整的保证dispatchingValue执行完毕。

    val mBanner=MutableLiveData<List<Banner>>()
    fun test(){
        println("1")
        try {
            mBanner.observe(this){
                try {
                    println("2")
                    throw  RuntimeException("奔溃了")
                    println("3")
                }catch (e:Exception){

                }
            }
        }catch (e:Exception){

        }
        println("4")
    }

我们封装下,重写一个LiveData的扩展函数,如下的方法所示,为的就是给回调的方法给try catch下,保证这个回调方法能执行完,避免dispatchingValue执行不完: 

fun <T> MutableLiveData<T>.safeObserve(owner: LifecycleOwner, onChange: (T) -> Unit) {
    this.observe(owner) {
        try {
            onChange(it)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Java 中使用 LiveData,可以按照以下步骤进行操作: 1. 导入 LiveData 类:首先,确保已经导入 LiveData 类,以便在代码中使用它。 ```java import androidx.lifecycle.LiveData; ``` 2. 创建 LiveData 对象:在类中声明一个 LiveData 对象,并指定其数据类型。 ```java private LiveData<String> messageLiveData; ``` 3. 初始化 LiveData 对象:在类的构造函数或其他适当的位置,为 LiveData 对象分配一个初始值。 ```java messageLiveData = new MutableLiveData<>(); ``` 4. 观察 LiveData:使用 `observe()` 方法观察 LiveData 对象的变化,并在回调方法中处理更新的数据。 ```java messageLiveData.observe(this, new Observer<String>() { @Override public void onChanged(String message) { // 在这里处理 LiveData 更新的数据 } }); ``` 5. 更新 LiveData 数据:通过更新 LiveData 对象的值来通知观察者。在需要更新数据的地方,可以调用 MutableLiveData 的 `setValue()` 或 `postValue()` 方法。 ```java // 在主线程中更新 LiveData 的值 ((MutableLiveData<String>) messageLiveData).setValue("New message"); // 在工作线程中更新 LiveData 的值 ((MutableLiveData<String>) messageLiveData).postValue("New message"); ``` 需要注意的是,对于可变的 LiveData 对象,如 MutableLiveData,可以使用 `setValue()` 方法在主线程中更新数据,或者使用 `postValue()` 方法在工作线程中更新数据。对于不可变的 LiveData 对象,如通过 LiveData 的子类创建的对象,则只能通过创建新的 LiveData 对象来传递新的值。 通过以上步骤,你可以在 Java 中使用 LiveData 进行数据观察和更新。LiveData 提供了一种方便的机制来处理数据的观察和通知,以实现响应式编程的模式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值