Retrofit 2 - 如何异步显示进度条?
Posted
技术标签:
【中文标题】Retrofit 2 - 如何异步显示进度条?【英文标题】:Retrofit 2 - How show progress bar async? 【发布时间】:2016-12-24 02:16:38 【问题描述】:我在 android 中创建新项目时创建了默认登录活动。 默认情况下会创建一个progressBar,可以很好地登录并正确显示。这一切都是通过 AsyncTask 实现的。
现在我使用 Retrofit 2 让路异步登录。
当我按下按钮登录时启动了一个方法,内容:
....
....
showProgress(true);
call.enqueue(new Callback<User>()
@Override
public void onResponse(Call<User> call, retrofit2.Response<User> response)
try
Thread.sleep(3000);
catch (InterruptedException e)
e.printStackTrace();
User userdatos = response.body();
if(userdatos != null)
// redirect to Main Activity page
showProgress(false);
Intent i = new Intent(LoginActivity.this, MainActivity.class);
startActivity(i);
else
showProgress(false);
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
@Override
public void onFailure(Call<User> call, Throwable t)
call.cancel();
showProgress(false);
Toast.makeText(LoginActivity.this, "Please check your network connection and internet permission", Toast.LENGTH_LONG).show();
);
我强制 Thread.sleep (3000) 检查。 没有进度条出现,调试显示: 跳过了 180 帧!应用程序可能在 ITS 主线程上做了太多工作。
如何解决?
我会有很多异步调用,我总是会显示一个进度条来等待响应完成。
谢谢
【问题讨论】:
你不应该在 UI 线程上调用Thread.sleep()
。
mmmm.... oki... 但是:从那以后我模拟请求需要几秒钟?这样才能保证进度条显示出来?另外,我认为使用 Retrofit 2 进行调用,所以 Async,会喜欢 AsyncTask。
我认为问题在于您的 showProgress 实现或该调用执行速度如此之快,并且您看不到进度条,因为它立即显示/隐藏。如果您添加延迟而不是睡眠(处理程序帖子),您将看到一个进度条。
感谢@Beloo,调用执行速度如此之快...... O_o。我尝试使用 hadlet post 添加延迟,效果很好
【参考方案1】:
让我与您分享由 Android Studio 创建的默认登录活动的代码实现和我的 Retrofit 实现。默认登录活动,包括AsyncTask
,它称为UserLoginTask
,在其中,我做了所有登录逻辑的东西。我使用.execute
而不是.enqueue
,因为它是同步的,我们不需要AsyncTask
中的新线程
public class UserLoginTask extends AsyncTask<Void, Void, Boolean>
private final String mEmail;
private final String mPassword;
UserLoginTask(String email, String password)
mEmail = email;
mPassword = password;
@Override
protected Boolean doInBackground(Void... params)
Retrofit restAdapter = new Retrofit.Builder()
.baseUrl(Constants.ROOT_API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
IConstructSecureAPI service = restAdapter.create(IConstructSecureAPI.class);
Call<JsonElement> result = service.getToken(mEmail, mPassword, "password");
try
//using sync request and get response
JsonElement element = result.execute().body();
if(element!=null)
//do whatever you want with your response
catch (IOException e)
e.printStackTrace();
return false;
return true;
@Override
protected void onPostExecute(final Boolean success)
mAuthTask = null;
showProgress(false);
if (success)
if(clientType != 2)
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
clientType = 0;
else
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivityForResult(intent, 1);
// finish();
else
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
@Override
protected void onCancelled()
mAuthTask = null;
showProgress(false);
【讨论】:
感谢您的代码。在我的一项测试中,我做到了。但我有一个问题:我们想使用 Rretrofit 2 Sync 和 AsyncTask 的原因是什么,可以使用 Retrofit 2 Async 吗?谢谢 @daicon 当然可以,但是在您的问题中,我没有看到您所有的活动代码。我也不明白你写了什么 sleep 。一般来说,你的问题对我来说不是很清楚,你是否有改造问题或 UI 的一些异常,或者只是看到警告“ITS 主线程上的工作太多”?【参考方案2】:无耻宣传
我为此创建了RxLoading library,它可以做到这一点以及更多,
你可以这样做:
networkCall().compose(RxLoading.<>create(loadingLayout)).subscribe(...);
它由 2 个类组成,一个自定义视图 (loadingLayout) 和 RxLoading,它是一个 transformer,将它们粘合在一起,您可以选择同时使用它们或其中之一。
不过,您需要在 RxJava 中使用 retrofit2。
RxLoading 还支持空和错误状态(具有内置重试机制,因此请务必检查此选项)
您可以通过GitHub page了解更多信息。
【讨论】:
以上是关于Retrofit 2 - 如何异步显示进度条?的主要内容,如果未能解决你的问题,请参考以下文章