我如何等待Retrofit异步Web服务调用? (call.enqueue)

时间:2018-02-16 18:37:42

标签: java android retrofit retrofit2

我是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);

}

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

在android中,阻止ui的网络或繁重任务无法在主线程上完成,因此所有这些事情都是异步完成的。 为了实现您的目标,您需要在网络呼叫完成后调用所有后续步骤,这只能在onResponseonFailure内的改进回调中完成。它基本上是通话链接。为了使代码更具可读性,您可以使用自己的接口进行回调机制,也可以使用RxJava这样的库,这使得它非常简单。