Android Activity发送请求时如何正确显示加载布局
为什么你的写法不生效
核心原因是Android的UI渲染全在主线程跑,你写的三段代码全是同步顺序在主线程执行的:
- 第一次调用
setContentView(R.layout.loading)只是把loading布局的视图层级挂到了Window上,根本没等系统走完测量、布局、绘制的渲染流程,就立刻执行了sendRequests() - 如果
sendRequests()是同步网络请求,会直接把主线程堵死,UI渲染完全停摆,loading界面根本没机会画到屏幕上 - 等请求跑完,你直接调用
setContentView(R.layout.main)切到主布局,用户从始至终都看不到loading状态,只会看到最终加载完的主界面。
另外提一句,从Android 3.0开始,主线程执行同步网络请求会直接抛NetworkOnMainThreadException,就算你不管loading的问题,这么写本身也会触发崩溃或者ANR。
正确实现方式
别用两次setContentView的思路,选下面任意一种稳妥方案就行:
- 主布局内置双状态容器
主布局里同时放loading布局和业务内容布局,默认只显示loading、隐藏内容,等请求全部返回后再切状态,这是最通用、性能最好的写法:
对应Activity逻辑:<!-- R.layout.main 示例结构 --> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 业务内容区,默认隐藏 --> <LinearLayout android:id="@+id/content_wrap" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="gone"> <!-- 你的主界面所有控件放这 --> </LinearLayout> <!-- 加载态布局,默认显示 --> <LinearLayout android:id="@+id/loading_wrap" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <ProgressBar android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> </FrameLayout>@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); View contentWrap = findViewById(R.id.content_wrap); View loadingWrap = findViewById(R.id.loading_wrap); // 网络请求必须扔到子线程跑,别堵主线程 new Thread(() -> { Object requestResult = sendRequests(); // 切回主线程更新UI runOnUiThread(() -> { // 先把请求的数据绑定到内容区的控件上 bindDataToViews(requestResult); // 切换显示状态 loadingWrap.setVisibility(View.GONE); contentWrap.setVisibility(View.VISIBLE); }); }).start(); } - 全屏加载弹窗方案
进入页面先弹一个不可取消的全屏loading弹窗,等所有请求完成后关闭弹窗,再给主界面控件绑定数据。这个方案改动量小,适合不想改现有主布局结构的场景。 - ViewStub懒加载方案
如果主布局本身inflate就很重,可以一开始只setContentView放loading的简单布局,等请求跑完后,再通过ViewStub把主布局inflate进来替换掉loading,核心还是要保证请求在子线程执行,给主线程留出渲染loading的时间。
注意:不管选哪种方案,都绝对不要在主线程执行耗时的网络请求、IO操作,否则不光加载态显示不出来,应用还会出现卡顿、无响应甚至崩溃的问题。
内容的提问来源于stack exchange,提问作者RyukGodOfTheDeathhh
相关产品推荐
相关产品推荐

