Java中回调方法内赋值的变量在外部访问返回null的原因及解决
问题原因
这是异步回调的执行时序问题,你传入的onCallback方法不是和外层代码同步执行的:
- 外层代码是主线程按顺序同步执行的:初始化Channel实例、调用
getChann()、注册回调、执行channel+="1"、打印Channel1日志,这几步执行时onCallback还没有被触发,channel还没有被赋值,自然读到的是null。 onCallback只有等getChann()触发的异步任务(比如网络请求、子线程任务)执行完成后才会被调用,此时才会给channel赋值,所以你在回调内部打印能拿到正确值。
解决方案
核心思路是等回调执行完成后,再处理需要用到channel的逻辑,常用实现方式有两种:
1. 直接把逻辑放到回调内部(最简单)
把所有需要用到channel的逻辑都移到onCallback方法里即可:
ch = new Channel(fuser.getUid(),userid); ch.getChann(); ch.Back(new Channel.MyCallback() { @Override public void onCallback(String value) { String channel = value; Log.e("Channel",channel); // 后续需要用到channel的逻辑都写在这里 String channel1 = channel + "1"; Log.e("Channel1",channel1); } });
2. 使用可观察容器做通知(适合逻辑拆分场景)
如果不想把所有逻辑都塞到回调里,可以用LiveData这类可观察数据容器,监听数据变化后再执行逻辑:
首先定义可观察的Channel数据:
MutableLiveData<String> channelLiveData = new MutableLiveData<>();
回调里给LiveData赋值:
@Override public void onCallback(String value) { channelLiveData.postValue(value); }
在需要用到channel的地方监听数据变化:
channelLiveData.observe(this, channel -> { // 这里写需要用到channel的逻辑 String channel1 = channel + "1"; Log.e("Channel1",channel1); });
注意:不要用主线程轮询或者加锁等待的方式等回调执行,会卡住主线程甚至引发ANR问题。
内容的提问来源于stack exchange,提问作者user15660680
相关产品推荐
相关产品推荐

