Retrofit2 enqueue onResponse 和 onFailure 未执行

问题描述

我是 android retrofit2 的新手。我正在尝试使用访问和刷新令牌加载我的登录响应,但 .enqueue() 能够连接到后端并获得响应。但是发布响应 onResponse 和 onFailure 没有得到执行。

代码@github

改造实例.java:

public class RetrofitInstance {
private static Retrofit retrofit = null;


public static Retrofit getRetrofitInstance(String url) {

    if (null==retrofit){
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(httpLoggingInterceptor)
                .readTimeout(3000,TimeUnit.MILLISECONDS)
                .connectTimeout(4000,TimeUnit.MILLISECONDS)
                .callTimeout(5000,TimeUnit.MILLISECONDS)
                .writeTimeout(3000,TimeUnit.MILLISECONDS)
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) //for RXjava
                .client(okHttpClient)
                .build();
    }
    return retrofit;
}}

apiclient.java

public class apiclient {

private static final String BASE_URL = "http://192.168.0.10:8080/";

public static LoginService getLoginService(){
    return RetrofitInstance.getRetrofitInstance(BASE_URL).create(LoginService.class);
}}

登录服务.java:

public interface LoginService {

@POST("accounts/api/token/")
Call<LoginResponse> getAuthToken(@Body LoginRequest loginRequest);

@POST("accounts/api/token/refresh/")
Observable<LoginResponse> refreshAuthToken(@Body LoginResponse refreshRequest);}

登录响应.java

public class LoginResponse {

@Serializedname("access")
@Expose
private String access;
@Serializedname("refresh")
@Expose
private String refresh;
@Serializedname("detail")
@Expose
private String detail;

public void setAccess(String access) {
    this.access = access;
}

public void setRefresh(String refresh) {
    this.refresh = refresh;
}

public void setDetail(String detail) {
    this.detail = detail;
}

public String getDetail() {
    return detail;
}

public String getAccess() {
    return access;
}

public String getRefresh() {
    return refresh;
}

public LoginResponse(String access,String refresh) {
    this.access = access;
    this.refresh = refresh;
}

public LoginResponse(String detail) {
    this.detail = detail;
}

public LoginResponse() {
}}

登录.java

Call<LoginResponse> loginResponseCall = service.getAuthToken(new LoginRequest(username,password));
        CountDownLatch countDownLatch = new CountDownLatch(1);
        loginResponseCall.enqueue(new Callback<LoginResponse>() {
            @Override
            public void onResponse(Call<LoginResponse> call,Response<LoginResponse> response) {
                Log.d("#Login","Result: " + response);
                if (response.isSuccessful()) {
                    if (response.body() != null) {
                        loggedInUser = new LoggedInUser(response.body());
                    }
                }else {
                    Log.e("#Login","error: "+ (response.body() != null ? response.body() : null));
                }
                countDownLatch.countDown();
            }

            @Override
            public void onFailure(Call<LoginResponse> call,Throwable t) {
            Log.e("#Login","Exception at subscription");
            countDownLatch.countDown();
            }
        });
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            Log.e("#Login","Exception in countDownLatch.await() "+e.getMessage());
        }

错误响应:

{
  "detail": "No active account found with the given credentials"
}

正确答案:

{
"refresh": "JWT refresh token","access": "JWT access token"
}

Logcat:

D/NetworkSecurityConfig: No Network Security Config specified,using platform default
I/Okhttp.OkHttpClient: --> POST http://192.168.0.10:8080/accounts/api/token/
I/Okhttp.OkHttpClient: Content-Type: application/json; charset=UTF-8
I/Okhttp.OkHttpClient: Content-Length: 45
I/Okhttp.OkHttpClient: {"password":"password","username":"user"}
I/Okhttp.OkHttpClient: --> END POST (45-byte body)
I/Okhttp.OkHttpClient: <-- 200 OK http://192.168.0.10:8080/accounts/api/token/ (678ms)
I/Okhttp.OkHttpClient: Date: Sun,06 Jun 2021 13:54:55 GMT
I/Okhttp.OkHttpClient: Server: WsgiServer/0.2 cpython/3.9.5
I/Okhttp.OkHttpClient: Content-Type: application/json
I/Okhttp.OkHttpClient: vary: Accept
I/Okhttp.OkHttpClient: Allow: POST,OPTIONS
I/Okhttp.OkHttpClient: x-frame-options: DENY
I/Okhttp.OkHttpClient: Content-Length: 494
I/Okhttp.OkHttpClient: X-Content-Type-Options: nosniff
I/Okhttp.OkHttpClient: Referrer-Policy: same-origin
I/Okhttp.OkHttpClient: {"refresh":"JWT refresh token","access":"JWT access token"}
I/Okhttp.OkHttpClient: <-- END HTTP (494-byte body)

发布此倒计时闩锁不会归零,线程正在等待。请对此提供帮助。我也试过 rxjava2 但没有运气

解决方法

我也遇到了同样的问题。请在清单的应用程序标签中添加这一行。我希望它也能帮助你。

android:usesCleartextTraffic="true"