我对具有以下 struct 的服务器进行了异步调用:

AuthAPI authAPI = retrofitService.getRetrofit().create(AuthAPI.class);

authAPI.registerUser(requestBody)
    .enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(@NonNull Call<ResponseBody> call,
            @NonNull Response<ResponseBody> response) {
            // Response processing.
        }

        @Override
        public void onFailure(@NonNull Call<ResponseBody> call,
            @NonNull Throwable t) {
            // Failure processing.
        }
    });

此代码在按钮的onClick()方法内执行.在此代码之后,新的片段将替换当前代码,但当此代码由于.enqueue()是异步的而执行时,异步部分尚未完成,因此应用程序将崩溃.因此,我需要等待执行异步代码,然后显示新的片段.

我可以使用execute()方法而不是enqueue()方法,但如果我理解正确的话,在execute()方法完成之前,整个UI线程将被冻结,ProgressBar动画将不会运行.这对我来说也不好.

所以,我要问的是,我如何等待服务器响应被处理,而不锁定我的UI线程,而让ProgressBar旋转?

推荐答案

是的,您应该在开始前显示一些进度条,然后将其隐藏在onResponse中,然后,您可以显示您的片段,以下是一些代码:

progressBar.setVisibility(View.VISIBLE);
authAPI.registerUser(requestBody).enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(@NonNull Call<ResponseBody> call,
                           @NonNull Response<ResponseBody> response) {
        // Response processing.
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                progressBar.setVisibility(View.GONE); // hide progress bar when response is received
                
                // Replace the current fragment with the new fragment here
                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                NewFragment newFragment = new NewFragment();
                fragmentTransaction.replace(R.id.fragment_container, newFragment);
                fragmentTransaction.commit();
            }
        });
    }

    @Override
    public void onFailure(@NonNull Call<ResponseBody> call,
                          @NonNull Throwable t) {
        // Failure processing.
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                progressBar.setVisibility(View.GONE); // hide progress bar when response fails
            }
        });
    }
});

使用runOnUiThread的原因是为了确保视图更新和片段事务将在主UI线程上发生,而不是在enqueue操作所在的后台线程上发生,因此它不会引发异常!

Java相关问答推荐

neo4j java驱动程序是否会在错误发生时自动回滚事务?

使用动态ID从json获取详细信息的Jolt规范

';com.itextpdf.ext.html.WebColors已弃用

对某一Hyroby控制器禁用@cacheable

对Java中的通配符参数的混淆

在Java中如何从Executors.newFixedThreadPool(MAX_THREAD_COUNT())迁移到虚拟线程

如何使用带有谓词参数的方法,而不使用lambda表达式

如何让JavaFx应用程序识别依赖项?

测试容器无法加载类路径初始化脚本

Java中将文本拆分为数字或十进制数字和字符串

如何在JavaFX中处理多个按钮

Spring动态反序列化JSON可以是列表,也可以只是一个对象

AbstractList保证溢出到其他方法

Java 21中泛型的不兼容更改

如何通过Java java.lang.Foreign API访问本机字节数组

JavaFX复杂项目体系 struct

Kotlin-仅替换字符串中最后一个给定的字符串

多线程、并发和睡眠未按预期工作

读取ConcurrentHashMap中的可变对象

为什么child-pom会创建一个新版本