You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Retrofit处理搜索无效数据:天气APP无效城市输入崩溃解决

嘿,这个问题我熟!之前帮朋友调试天气APP的时候也碰到过一模一样的情况——用户乱输一串字符就崩溃,核心原因就是咱们没处理API返回的错误状态,也没做前置的输入校验。咱们分几步搞定:

解决步骤

1. 先给用户输入加一层前置校验

在调用API之前,先把明显无效的输入拦下来,比如空字符串、纯空格、带特殊字符的乱码。这样既能减少无效的API请求,也能提前给用户提示。

示例代码(假设你用EditText接收输入):

// 获取用户输入并去除首尾空格
String inputCity = cityEditText.getText().toString().trim();

// 校验1:不能是空输入
if (inputCity.isEmpty()) {
    Toast.makeText(this, "请输入有效的城市名称", Toast.LENGTH_SHORT).show();
    return;
}

// 校验2:简单过滤特殊字符(可选,比如只允许中英文、空格和少数合法符号)
if (!inputCity.matches("[a-zA-Z\\u4e00-\\u9fa5\\s]+")) {
    Toast.makeText(this, "请输入有效的城市名称", Toast.LENGTH_SHORT).show();
    return;
}

// 校验通过,再调用API
getWeatherDataByCity(inputCity);

2. 处理API响应的错误状态

OpenWeatherMap API查询无效城市时,会返回404状态码,同时响应体里会提示"city not found"。咱们必须在网络请求的回调里判断响应是否成功,不能直接解析数据。

如果你用OkHttp,修改请求逻辑如下:

private void getWeatherDataByCity(String city) {
    HashMap<String, String> params = new HashMap<>();
    params.put("q", city);
    params.put("appid", "你的API_KEY");
    params.put("units", "metric"); // 按需设置单位,比如摄氏度

    OkHttpClient client = new OkHttpClient();
    Request request = new Request.Builder()
            .url("https://api.openweathermap.org/data/2.5/weather")
            .get()
            .params(new FormBody.Builder().addAll(params).build())
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(@NonNull Call call, @NonNull IOException e) {
            // 网络请求失败(比如无网)的情况
            runOnUiThread(() -> {
                Toast.makeText(MainActivity.this, "网络连接失败,请稍后重试", Toast.LENGTH_SHORT).show();
            });
        }

        @Override
        public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
            runOnUiThread(() -> {
                // 先判断响应是否成功(状态码200-299)
                if (!response.isSuccessful()) {
                    // 状态码不对,比如404就是城市不存在
                    Toast.makeText(MainActivity.this, "请输入有效的城市名称", Toast.LENGTH_SHORT).show();
                    return;
                }

                // 正常解析数据的逻辑,一定要加try-catch防止解析崩溃
                try {
                    String responseBody = response.body().string();
                    // 这里写你的JSON解析代码,比如解析城市名、温度等
                    JSONObject jsonObj = new JSONObject(responseBody);
                    String cityName = jsonObj.getString("name");
                    // ...其他字段解析
                } catch (Exception e) {
                    // 解析出错(比如API返回格式变动)
                    Toast.makeText(MainActivity.this, "数据解析失败,请稍后重试", Toast.LENGTH_SHORT).show();
                    e.printStackTrace();
                }
            });
        }
    });
}

如果用Retrofit,处理方式类似:

// 假设你已经定义了WeatherResponse实体类和WeatherApi接口
Call<WeatherResponse> call = weatherApi.getWeatherByCity(city, "你的API_KEY");
call.enqueue(new Callback<WeatherResponse>() {
    @Override
    public void onResponse(Call<WeatherResponse> call, Response<WeatherResponse> response) {
        if (!response.isSuccessful()) {
            // 响应失败,提示用户
            Toast.makeText(MainActivity.this, "请输入有效的城市名称", Toast.LENGTH_SHORT).show();
            return;
        }
        // 正常处理返回数据
        WeatherResponse weatherData = response.body();
        if (weatherData != null) {
            // 更新UI显示天气信息
        }
    }

    @Override
    public void onFailure(Call<WeatherResponse> call, Throwable t) {
        // 网络失败提示
        Toast.makeText(MainActivity.this, "网络连接失败", Toast.LENGTH_SHORT).show();
    }
});

3. 关键提醒:给解析逻辑加try-catch

就算API返回成功,也可能因为JSON格式变动、字段缺失等原因导致解析崩溃,所以一定要把解析代码放在try-catch块里,捕获异常并提示用户。

这样一套操作下来,不管用户是乱输字符、网络不好还是API返回错误,APP都不会崩溃,而是友好地给用户提示~

内容的提问来源于stack exchange,提问作者chand mohd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:59:06