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

Android新手求助:天气API数据获取代码无输出问题排查

解决你的天气API请求无输出问题

兄弟,我仔细排查了你的代码,发现几个核心问题,这些就是导致请求无输出、Logcat没内容的关键原因:

1. 流读取的循环条件完全错误

在doInBackground方法里,你写了while (data !=1),但InputStreamReader.read()方法返回**-1**才代表到达流的末尾,返回1只是某个字符的ASCII值。这个错误会导致循环要么直接不执行,要么读取一个字符就终止,最终result是空字符串或不完整内容,后续JSON解析自然会失败。

正确的条件应该是:

while (data != -1)

2. 子线程调用Toast会导致崩溃

doInBackground运行在子线程中,而Toast.makeText必须在主线程执行,你在catch块里调用Toast会直接导致线程崩溃、任务终止,这也是你看不到任何输出的重要原因之一。Toast提示逻辑应该移到onPostExecute方法(该方法在主线程执行)中。

3. JSON解析路径错误

你调用的openweathermap forecast接口中,天气数据并不在weather字段下,而是嵌套在list数组的每个元素里的weather子数组中。原来的解析逻辑完全找错了数据路径,即使拿到了正确的API返回,也无法解析出内容。

4. 流读取效率优化(可选)

你逐个字符拼接字符串的方式效率极低,建议用BufferedReader+StringBuilder优化读取逻辑,避免内存浪费。


修改后的完整代码示例

下面是修正了所有关键问题的代码:

// 先修正类名拼写:DownloasTask → DownloadTask
public class DownloadTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        String result = "";
        URL url;
        HttpURLConnection urlConnection = null;
        try {
            url = new URL(urls[0]);
            urlConnection = (HttpURLConnection) url.openConnection();
            InputStream in = urlConnection.getInputStream();
            
            // 优化流读取方式
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            result = sb.toString();
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("Exception", "URL请求失败:" + e.getMessage());
            // 子线程禁止弹Toast,仅打印日志
            return null;
        } finally {
            // 关闭连接,避免资源泄漏
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        // 先判断返回结果是否为空
        if (result == null || result.isEmpty()) {
            Toast.makeText(getApplicationContext(), "无法获取天气数据", Toast.LENGTH_SHORT).show();
            return;
        }
        
        try {
            JSONObject jsonObject = new JSONObject(result);
            // 正确获取forecast接口的天气数据数组
            JSONArray listArr = jsonObject.getJSONArray("list");
            String message = "";
            
            for (int i = 0; i < listArr.length(); i++) {
                JSONObject listItem = listArr.getJSONObject(i);
                // 每个list项中的weather子数组
                JSONArray weatherArr = listItem.getJSONArray("weather");
                if (weatherArr.length() > 0) {
                    JSONObject weatherObj = weatherArr.getJSONObject(0);
                    String main = weatherObj.getString("main");
                    String description = weatherObj.getString("description");
                    
                    if (!main.isEmpty() && !description.isEmpty()) {
                        message += main + ": " + description + "\r\n";
                    }
                    Log.i("main", main);
                    Log.i("description", description);
                }
            }
            
            if (!message.isEmpty()) {
                textView2.setText(message);
            } else {
                Toast.makeText(getApplicationContext(), "未找到天气详情", Toast.LENGTH_SHORT).show();
            }
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("JSON解析错误", "解析天气数据失败:" + e.getMessage());
            Toast.makeText(getApplicationContext(), "解析天气数据失败", Toast.LENGTH_SHORT).show();
        }
    }
}

public void getWeather(View view) {
    String city = editText.getText().toString().trim();
    // 先判断输入是否为空
    if (city.isEmpty()) {
        Toast.makeText(getApplicationContext(), "请输入城市名称", Toast.LENGTH_SHORT).show();
        return;
    }
    
    DownloadTask task = new DownloadTask();
    // 注意:确保你的appid是有效的,示例id可能有访问限制
    task.execute("https://openweathermap.org/data/2.5/forecast?q=" + city + "&appid=b1b15e88fa797225412429c1c50c122a1");
    
    InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}

额外注意事项

  • 别忘了在AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" />,否则网络请求会直接失败。
  • AsyncTask在Android 11及以上版本已被废弃,建议后续学习使用Coroutines或Retrofit等主流网络请求方案。
  • 你使用的appid看起来是示例id,建议注册一个自己的有效openweathermap账号获取appid,避免请求被限制。

内容的提问来源于stack exchange,提问作者gouri panda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:41:45