Android如何仅在API请求耗时超1秒时显示LoadingDialog弹窗
延迟加载弹窗实现方案(避免弹窗闪屏)
核心实现逻辑:取消发起请求即弹窗的逻辑,改为提交一个1秒后执行的弹窗任务到主线程:
- 若接口在1秒内返回,直接取消未执行的弹窗任务,全程不展示弹窗,从根源避免弹窗一闪而过的问题
- 若接口耗时超过1秒,延迟任务正常触发弹出加载框,请求返回后关闭弹窗,长耗时场景体验不受影响
实现要点
- 延迟任务必须和页面、请求生命周期绑定,请求返回、页面销毁时第一时间取消未执行的弹窗任务,避免内存泄漏或页面退出后异常弹窗
- 废弃原有toggle式的弹窗控制方法,拆分独立的显示、关闭方法,增加状态标记位,避免连续调用导致弹窗状态错乱
- 所有弹窗操作必须在主线程执行,避免Fragment操作崩溃
完整实现代码
首先在对应Activity中添加必要的成员变量:
// 主线程Handler,用于调度延迟弹窗任务 private final Handler mainHandler = new Handler(Looper.getMainLooper()); // 加载弹窗展示状态标记 private boolean isLoadingShow = false; // 延迟弹窗任务实例 private Runnable loadingShowRunnable;
拆分原有的弹窗控制逻辑为独立的显示、关闭方法:
/** * 显示加载弹窗,做重复校验避免重复创建 */ private void showLoading() { if (isLoadingShow) return; Fragment existFragment = getSupportFragmentManager().findFragmentByTag(LoadingDialog.TAG); if (existFragment instanceof LoadingDialog) { isLoadingShow = true; return; } new LoadingDialog().show(getSupportFragmentManager(), LoadingDialog.TAG); isLoadingShow = true; } /** * 关闭加载弹窗,做状态校验避免重复关闭 */ private void dismissLoading() { if (!isLoadingShow) return; Fragment existFragment = getSupportFragmentManager().findFragmentByTag(LoadingDialog.TAG); if (existFragment instanceof LoadingDialog) { ((LoadingDialog) existFragment).dismissAllowingStateLoss(); } isLoadingShow = false; }
修改接口请求逻辑,加入延迟弹窗控制:
private void getTable(String tableNumber) { // 先清理上一次请求残留的延迟任务,避免逻辑干扰 if (loadingShowRunnable != null) { mainHandler.removeCallbacks(loadingShowRunnable); } // 初始化1秒延迟弹窗任务 loadingShowRunnable = this::showLoading; mainHandler.postDelayed(loadingShowRunnable, 1000); Ion.with(getApplicationContext()) .load("http://" + ip + "/webquery/?FINDTAV=" + tableNumber + "&v2=true") .setTimeout(10000) .asString() .setCallback((e, result) -> { // 收到响应第一时间取消未执行的弹窗任务 mainHandler.removeCallbacks(loadingShowRunnable); // 关闭已弹出的加载弹窗 dismissLoading(); // 执行业务逻辑 // DOING STUFF }); }
生命周期安全处理
必须在Activity的
onDestroy方法中清理未执行的任务、关闭弹窗,避免页面销毁后任务执行触发崩溃:@Override protected void onDestroy() { super.onDestroy(); if (loadingShowRunnable != null) { mainHandler.removeCallbacks(loadingShowRunnable); } dismissLoading(); }
内容的提问来源于stack exchange,提问作者NiceToMytyuk
相关产品推荐
相关产品推荐

