【发布时间】:2018-02-17 04:34:42
【问题描述】:
我是 java/android 新手,之前在 C# 中使用异步调用做了很多工作,我可以使用 await 来强制响应,然后再转到更多代码。
据我所知, call.enqueue 是异步的,但我希望等待它,以便我的 LoginActivity 方法可以根据登录是否成功来处理后续步骤。
我做了一些日志,理想情况下应该显示如下:
FIRST
SECOND
THIRD
FOURTH
但是由于异步,我反而得到:
FIRST
SECOND
FOURTH
THIRD
LoginActivity.java
public boolean tryLoginAttempt(LoginRequest request) {
// Call login service, login method
LoginService service = new LoginService();
Log.d(TAG, "FIRST");
LoginResponse loginResponse = service.loginMethod(request); // ** want to await this
Log.d(TAG, "FOURTH");
// If login works, navigate to tabbed menu
if (loginResponse.getAuthorized()) {
Intent intent = new Intent(LoginActivity.this, SelectTeamActivity.class);
startActivity(intent);
}
return loginResponse.getAuthorized();
}
LoginService.java
LoginResponse mLoginResponse = new LoginResponse();
public LoginResponse loginMethod(LoginRequest request) {
try {
String baseUrl = "https://myurl.com";
// Create retrofit object
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build(); // This instantiates the Retrofit builder we will need for REST calls
LoginEndpointInterface apiService = retrofit.create(LoginEndpointInterface.class);
// Call the login method
Observable<LoginResponse> call = apiService.login(request);
Log.d(TAG, "SECOND");
call.enqueue(new Callback<LoginResponse>() { // ** running as async
@Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
Log.d(TAG, "THIRD");
int statusCode = response.code();
// Login worked
if (response.body().getAuthorized()) {
Log.d(TAG, "Login worked");
mLoginResponse = response.body();
} else {
Log.d(TAG, "Login failed");
}
}
@Override
public void onFailure(Call<LoginResponse> call, Throwable t) {
Log.d(TAG, "ERROR in web service call: " + t.toString());
}
});
Log.d(TAG, "returning result of login check: " + result);
} catch(Exception ex) {
ex.printStackTrace();
}
return mLoginResponse;
}
改造调用接口
public interface LoginEndpointInterface {
@POST("api/login/")
retrofit2.Call<LoginResponse> login(@Body LoginRequest body);
}
感谢您的帮助!
【问题讨论】:
-
所以这段代码运行良好。使用 retrofit.enqueue 调用是异步完成的,并且每当从 BE 返回某些内容时都会执行回调。您的其他代码将继续执行。如果您想等到某些事情回来,您应该使用
call.execute,因为它是同步完成的。参考:square.github.io/retrofit/2.x/retrofit/retrofit2/…
标签: java android retrofit retrofit2