Android天气App中AsyncTask读取经纬度变量异常求助
嘿,作为Android新手遇到这个问题很正常,咱们直接揪出核心问题,一步步解决它!
核心问题:传参时多套了不必要的双引号
你在调用asyncTask.execute()的时候,给经纬度变量额外拼接了双引号:
asyncTask.execute('"' + latitude + '"', '"' + longitude + '"');
这会导致实际传给OpenWeatherMap API的参数是带引号的字符串(比如"52.2296756"),而API需要的是纯数字格式的经纬度(比如52.2296756)。
而你直接写asyncTask.execute("52.2296756", "38.3435546")时,Java代码里的双引号只是用来定义字符串字面量的,实际传递给API的是不带引号的纯数字内容,所以接口能正常返回数据。
修复方案
只需要去掉传参时的双引号拼接,直接传递变量即可:
asyncTask.execute(latitude, longitude);
额外的新手友好优化建议
除了核心问题,还有几个小细节可以优化,避免后续踩坑:
把UI初始化代码移到
onCreate中
你现在在onActivityResult里重复执行findViewById和控件初始化,这完全没必要,而且可能导致意外问题。把这些代码移到onCreate的末尾即可:@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getSupportActionBar().hide(); setContentView(R.layout.activity_main); // 初始化控件 mPlacePicker = (ImageView) findViewById(R.id.place_picker); weatherFont = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/weathericons-regular-webfont.ttf"); cityField = (TextView) findViewById(R.id.city_field); updatedField = (TextView) findViewById(R.id.updated_field); detailsField = (TextView) findViewById(R.id.details_field); currentTemperatureField = (TextView) findViewById(R.id.current_temperature_field); humidity_field = (TextView) findViewById(R.id.humidity_field); pressure_field = (TextView) findViewById(R.id.pressure_field); weatherIcon = (TextView) findViewById(R.id.weather_icon); weatherIcon.setTypeface(weatherFont); // PlacePicker点击事件 mPlacePicker.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // ... 原点击事件代码不变 } }); }移除
onActivityResult中重复的mPlacePicker赋值
你在onActivityResult里写了mPlacePicker = (ImageView) findViewById(place_picker);,这里不仅少了R.id.会报错,而且mPlacePicker已经是成员变量并在onCreate中初始化过了,直接删掉这行即可。增加空值判断
在执行AsyncTask前,先判断latitude和longitude是否为空,避免空指针异常:if (latitude != null && longitude != null) { asyncTask.execute(latitude, longitude); } else { Toast.makeText(this, "未能获取到有效坐标", Toast.LENGTH_SHORT).show(); }
修改后的完整onActivityResult代码
public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // 别忘了调用super方法! if (requestCode == PLACE_PICKER_REQUEST) { if (resultCode == RESULT_OK) { Place place = PlacePicker.getPlace(this, data); String address = String.format("Place %s", place.getAddress()); Toast.makeText(this, address, Toast.LENGTH_LONG).show(); LatLng latLng = place.getLatLng(); latitude = String.valueOf(latLng.latitude); longitude = String.valueOf(latLng.longitude); // 执行天气请求 Function.placeIdTask asyncTask = new Function.placeIdTask(new Function.AsyncResponse() { public void processFinish(String weather_city, String weather_description, String weather_temperature, String weather_humidity, String weather_pressure, String weather_updatedOn, String weather_iconText, String sun_rise) { cityField.setText(weather_city); updatedField.setText(weather_updatedOn); detailsField.setText(weather_description); currentTemperatureField.setText(weather_temperature); humidity_field.setText("Humidity: " + weather_humidity); pressure_field.setText("Pressure: " + weather_pressure); weatherIcon.setText(Html.fromHtml(weather_iconText)); } }); System.out.println(latitude); System.out.println(longitude); if (latitude != null && longitude != null) { asyncTask.execute(latitude, longitude); } else { Toast.makeText(this, "未能获取到有效坐标", Toast.LENGTH_SHORT).show(); } } } }
内容的提问来源于stack exchange,提问作者mistertumek

