【问题标题】:Retrofit onResponse and onFailure methods not getting called改造 onResponse 和 onFailure 方法没有被调用
【发布时间】:2019-06-27 05:03:32
【问题描述】:

当我调用 DarkSky API 时,对于某些位置,我的 onResponse 和 onFailure 方法不会被触发。我在美国测试了很多地方,一切都很好。我测试了伦敦,这很好,但是当我测试印度钦奈时,两种方法都没有触发。我还测试了被调用的 URL,当我将它放入网络浏览器时有响应,但它没有触发应用程序中的 onReponse() 方法。

我看到有人说这是因为调用是异步的,但我不知道为什么它会在某些城市实现 100% 一致性,而在其他城市却不行。

调用类:


import android.content.Context;
import android.content.SharedPreferences;
import android.widget.TextView;

import androidx.preference.PreferenceManager;

import com.jggdevelopment.simpleweather.BuildConfig;
import com.jggdevelopment.simpleweather.fragments.MasterFragment;
import com.jggdevelopment.simpleweather.models.Forecast;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class WeatherAPIUtils {

    private static String baseUrl = "https://api.darksky.net/forecast/" + BuildConfig.darkSkyAPI_KEY + "/";
    private static TextView temperatureView;
    private static TextView highTemp;
    private static TextView lowTemp;
    private static TextView description;
    private static TextView precipitationChance;
    private static SharedPreferences prefs;

    /**
     * uses retrofit to call the DarkSky API using the API key in the baseURL
     * @return WeatherService
     */
    private static WeatherService getWeatherService() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(baseUrl)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        return retrofit.create(WeatherService.class);
    }

    /**
     * Pulls weather data from the DarkSky API using the provided location.
     * On success, it updates the views in MasterFragment
     * @param lat latitude of location
     * @param lon longitude of location
     * @param fragment MasterFragment
     */
    public static void getCurrentWeatherData(Double lat, Double lon, final MasterFragment fragment) {
        WeatherService service = getWeatherService();
        prefs = fragment.getActivity().getSharedPreferences("com.jggdevelopment.simpleweather", Context.MODE_PRIVATE);

        if (prefs.getBoolean("useCelsius", false)) {
            service.getWeatherSI(lat, lon, "si").enqueue(new Callback<Forecast>() {
                @Override
                public void onResponse(Call<Forecast> call, Response<Forecast> response) {
                    if (response.isSuccessful()) {
                        fragment.updateConditions(response.body());
                    }
                }

                @Override
                public void onFailure(Call<Forecast> call, Throwable t) {

                }
            });
        } else {
            service.getWeatherImperial(lat, lon).enqueue(new Callback<Forecast>() {
                @Override
                public void onResponse(Call<Forecast> call, Response<Forecast> response) {
                    if (response.isSuccessful()) {
                        fragment.updateConditions(response.body());
                    }
                }

                @Override
                public void onFailure(Call<Forecast> call, Throwable t) {

                }
            });
        }
    }
}

POJO:


import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class Forecast {

    @SerializedName("currently")
    @Expose
    private Currently currently;
    @SerializedName("daily")
    @Expose
    private Daily daily;
    @SerializedName("flags")
    @Expose
    private Flags flags;
    @SerializedName("hourly")
    @Expose
    private Hourly hourly;
    @SerializedName("latitude")
    @Expose
    private Double latitude;
    @SerializedName("longitude")
    @Expose
    private Double longitude;
    @SerializedName("minutely")
    @Expose
    private Minutely minutely;
    @SerializedName("offset")
    @Expose
    private Integer offset;
    @SerializedName("timezone")
    @Expose
    private String timezone;

    public Currently getCurrently() {
        return currently;
    }

    public void setCurrently(Currently currently) {
        this.currently = currently;
    }

    public Daily getDaily() {
        return daily;
    }

    public void setDaily(Daily daily) {
        this.daily = daily;
    }

    public Flags getFlags() {
        return flags;
    }

    public void setFlags(Flags flags) {
        this.flags = flags;
    }

    public Hourly getHourly() {
        return hourly;
    }

    public void setHourly(Hourly hourly) {
        this.hourly = hourly;
    }

    public Double getLatitude() {
        return latitude;
    }

    public void setLatitude(Double latitude) {
        this.latitude = latitude;
    }

    public Double getLongitude() {
        return longitude;
    }

    public void setLongitude(Double longitude) {
        this.longitude = longitude;
    }

    public Minutely getMinutely() {
        return minutely;
    }

    public void setMinutely(Minutely minutely) {
        this.minutely = minutely;
    }

    public Integer getOffset() {
        return offset;
    }

    public void setOffset(Integer offset) {
        this.offset = offset;
    }

    public String getTimezone() {
        return timezone;
    }

    public void setTimezone(String timezone) {
        this.timezone = timezone;
    }

}```

【问题讨论】:

    标签: android retrofit2 darksky


    【解决方案1】:

    在这样的失败时输入登录网址

    @Override
            public void onFailure(Call<Response> call, Throwable t) {
                t.printStackTrace();
    
    
            }
    

    还添加了loggin拦截器来记录请求和响应

    public static OkHttpClient getHttpClient() {
    
            HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
            logging.setLevel(HttpLoggingInterceptor.Level.BODY);
    
    
    
            //TODO : remove logging interceptors as it is to be used for development purpose
            OkHttpClient client = new OkHttpClient.Builder()
                    .connectTimeout(300, TimeUnit.SECONDS)
                    .readTimeout(300,TimeUnit.SECONDS).
                            addInterceptor(logging).
                            build();
    
            return client;
        }
    

    像这样添加到这里

     private static WeatherService getWeatherService() {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .client(getHttpClient())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
    
            return retrofit.create(WeatherService.class);
        }
    

    通过这样做至少您将能够识别问题

    【讨论】:

    • 非常有帮助,谢谢。我发现问题是 NumberFormatException。其中一个字段(时区偏移量)通常是整数,但在极少数情况下,例如 Chennai,它是双精度数,在本例中为 5.5。如何处理类型不一致的字段?
    • 你可以将时区设为 Double .. 因为 double 也可以存储 int
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 2020-07-04
    • 1970-01-01
    相关资源
    最近更新 更多