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

如何从void方法onLocationChanged传递URL至jsonParse调用天气API

解决方案与新手开发建议

首先,你的核心需求很清晰:在获取到设备位置后,生成天气API请求URL,然后调用jsonParse()方法发起网络请求并解析数据。咱们一步步来调整代码,同时给你一些新手友好的开发提示。

一、修改代码实现需求

1. 调整变量作用域与核心逻辑

首先要确保URL能被jsonParse()正确获取到,更规范的方式是把URL作为参数传给jsonParse()(避免依赖成员变量,代码更健壮)。同时,在onLocationChanged()中生成URL后,直接调用jsonParse()即可。

下面是修改后的完整代码示例:

// 定义成员变量:Volley请求队列(记得在onCreate中初始化)
private RequestQueue mQueue;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.your_layout);
    
    // 初始化Volley请求队列
    mQueue = Volley.newRequestQueue(this);
    
    // 这里初始化你的TextView控件:TV_temp_max、TV_temp_min等
    TV_temp_max = findViewById(R.id.tv_temp_max);
    TV_temp_min = findViewById(R.id.tv_temp_min);
    TV_temp = findViewById(R.id.tv_temp);
    TV_humidity = findViewById(R.id.tv_humidity);
    TV_country = findViewById(R.id.tv_country);
    TV_city = findViewById(R.id.tv_city);
}

@Override 
public void onLocationChanged(Location location) {
    // 先判断location是否为空,避免空指针异常
    if (location == null) {
        Log.e("LocationError", "获取到的位置为空");
        return;
    }
    
    // 生成天气API请求URL,添加units参数返回摄氏度(默认是开尔文)
    String weatherUrl = "https://api.openweathermap.org/data/2.5/weather?lat=" 
            + location.getLatitude() 
            + "&lon=" + location.getLongitude() 
            + "&appid=5d8fea5f1c9cdfe8af473504e5f9002a"
            + "&units=metric";
    
    Log.i("api", weatherUrl);
    // 调用jsonParse方法,把生成的URL传进去
    jsonParse(weatherUrl);
}

// 修改jsonParse方法,接收URL参数
private void jsonParse(String requestUrl) {
    JsonObjectRequest request = new JsonObjectRequest(
            Request.Method.GET, 
            requestUrl, 
            null, 
            new Response.Listener<JSONObject>() {
                @Override 
                public void onResponse(JSONObject response) {
                    try {
                        JSONObject weatherData = response.getJSONObject("main");
                        double temp = weatherData.getDouble("temp");
                        double tempHigh = weatherData.getDouble("temp_max");
                        double tempLow = weatherData.getDouble("temp_min");
                        double humidity = weatherData.getDouble("humidity");
                        
                        Log.i("JSONWork", weatherData.toString());
                        
                        // 用setText替换append,避免多次更新时文本累加
                        TV_temp_max.setText("Highest Temperature: " + tempHigh + "°C");
                        TV_temp_min.setText("Lowest Temperature: " + tempLow + "°C");
                        TV_temp.setText("Current Temperature: " + temp + "°C");
                        TV_humidity.setText("Humidity: %" + humidity);
                        
                        // 注意:城市名称在response根节点的"name"字段,不是sys里的
                        String city = response.getString("name");
                        JSONObject locationData = response.getJSONObject("sys");
                        String country = locationData.getString("country");
                        
                        TV_country.setText(country);
                        TV_city.setText(city);
                        
                    } catch (JSONException e) {
                        Log.e("JSONError", "解析JSON失败", e);
                        // 给用户显示友好的错误提示
                        Toast.makeText(getApplicationContext(), "数据解析失败", Toast.LENGTH_SHORT).show();
                    }
                }
            }, 
            new Response.ErrorListener() {
                @Override 
                public void onErrorResponse(VolleyError error) {
                    Log.e("VolleyError", "网络请求失败", error);
                    Toast.makeText(getApplicationContext(), "网络请求失败,请检查网络", Toast.LENGTH_SHORT).show();
                    error.printStackTrace();
                }
            });
    
    mQueue.add(request);
}

// 其他位置回调方法保持不变
@Override public void onStatusChanged(String s, int i, Bundle bundle) { }
@Override public void onProviderEnabled(String s) { }
@Override public void onProviderDisabled(String s) { }

二、新手开发关键建议

  • 变量作用域问题:避免使用局部变量传递跨方法的数据,要么用成员变量,要么像示例中那样把数据作为参数传递(更推荐,减少代码耦合)。
  • 空指针防护:永远要判断location是否为空,比如设备位置服务异常时可能返回null,直接调用location.getLatitude()会导致崩溃。
  • Volley队列初始化:必须在onCreate()中初始化RequestQueue,不要每次请求都新建,否则会浪费系统资源。
  • 权限申请:别忘了在AndroidManifest.xml中添加必要权限:
    <!-- 网络权限 -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- 位置权限 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    
    同时在代码中动态申请位置权限(Android 6.0+系统要求)。
  • API参数优化:添加&units=metric参数可以返回摄氏度(默认是开尔文,普通用户看不懂),如果需要华氏度可以替换为units=imperial。
  • UI更新注意:append()会不断累加文本,多次获取位置后会重复显示内容,建议用setText()替换。另外Volley的回调是在主线程执行的,所以可以直接更新UI,不用手动切换线程。
  • 异常处理:不要只打印日志,给用户显示友好的错误提示(比如Toast),提升App的使用体验。

内容的提问来源于stack exchange,提问作者P.Pascarella

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:02:40