Kotlin/Java如何实现函数延后执行直至另一函数完成,适配Android RecyclerView异步inflate场景
实现方案
方案1:标记位+待执行任务缓存(推荐,适配同线程无锁场景)
因为A的调用和B的回调在同一线程,不需要处理并发冲突,实现逻辑最简单,性能损耗最低:
- 在对象x中新增两个成员变量:布尔型标记
isBFinished记录B是否执行完成,若A可能被多次调用则用List<Runnable>缓存待执行的A任务,单次调用用单个Runnable即可。 - B执行完成触发回调时,先将
isBFinished置为true,再依次执行所有缓存的A任务,执行完成后清空缓存。 - 调用函数A时先判断标记位:
- 若
isBFinished为true:直接执行A的原有业务逻辑 - 若
isBFinished为false:将A的业务逻辑封装为Runnable存入缓存,暂不执行
- 若
代码示例
public class X { // 标记B是否执行完成 private boolean isBFinished = false; // 缓存待执行的A任务,多次调用场景用ArrayList<Runnable> private Runnable pendingATask; // B执行完成的回调方法 private void onBCompleted() { isBFinished = true; // 执行缓存的A任务 if (pendingATask != null) { pendingATask.run(); pendingATask = null; } } // 对外暴露的函数A public void functionA() { if (isBFinished) { // 直接执行原有逻辑 doAActualWork(); return; } // 未完成则缓存任务等待B执行结束 pendingATask = this::doAActualWork; } // A的实际业务逻辑 private void doAActualWork() { // 你原本的A方法逻辑,比如RecyclerView的视图绑定逻辑 } }
注意事项
禁止使用
CountDownLatch、ReentrantLock等阻塞式同步工具:由于A调用和B回调在同一线程,阻塞线程会导致B的回调永远无法被调度,直接触发死锁,若线程是Android主线程还会引发ANR。
RecyclerView场景适配优化
针对你异步inflate列表条目的场景,可以额外给ViewHolder增加数据缓存:异步inflate完成前onBindViewHolder被触发时,先把要绑定的数据源存在ViewHolder的成员变量中,等B(异步inflate)执行完成后,直接读取缓存的数据源绑定到真实视图上,不需要等待下一次onBindViewHolder回调,体验更流畅。
内容的提问来源于stack exchange,提问作者daniyelp
相关产品推荐
相关产品推荐

