[英]Android JSON Issue
我有一个活动,允许用户输入邮政编码或城市以获取天气信息。 然后将他们带到另一个显示信息的活动。 除非您返回第一个活动以输入其他邮政编码或城市,否则此方法可以正常工作。 当您将另一个位置放到第二个活动中以显示新位置的天气信息时,它将拉取第一个位置的信息。 例如,我放置在某个位置,然后转到第二项活动,它显示温度为64,湿度为88%。 然后,我返回第一个活动并输入一个新位置,然后转到第二个活动。它仍会提取第一个位置的信息,因此再次显示64%和88%。 有什么建议么?
这是我的代码。
第一次活动:
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
public class WeatherLocation extends Activity
{
EditText locationText;
TextView label;
Button getWeather;
String enteredText;
String url = "http://api.worldweatheronline.com/free/v1/weather.ashx?q=%s&format=json&num_of_days=5&key=37a5fj42xpyptvjgkhrx5rwu";
String newURL;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.weatherlocation);
locationText = (EditText) findViewById(R.id.locationText);
label = (TextView) findViewById(R.id.label);
getWeather = (Button) findViewById(R.id.showWeather);
locationText.setText("Current Location");
locationText.setOnEditorActionListener(new OnEditorActionListener()
{
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
{
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE)
{
enteredText = locationText.getText().toString();
enteredText = enteredText.replaceAll(" ", "+");
System.out.println(enteredText);
// hide the virtual keyboard
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
InputMethodManager.RESULT_UNCHANGED_SHOWN);
newURL = String.format(url, enteredText);
System.out.println("Formatted URL: " + newURL);
handled = true;
}
return handled;
}
});
getWeather.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Intent weather = new Intent(WeatherLocation.this, Weather.class);
weather.putExtra("INTENT_KEY_URL", newURL);
startActivity(weather);
}
});
}
}
第二项活动:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.TextView;
public class Weather extends WeatherLocation
{
static TextView currentTemp;
static TextView humidityText;
static ArrayList<String> values = new ArrayList<String>();
static String url;
static String fahr;
static String humidity;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.weather);
Intent intent = getIntent();
url = intent.getStringExtra("INTENT_KEY_URL");
Typeface kfb = Typeface.createFromAsset(getAssets(), "FranklinGothicStd-ExtraCond.otf");
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
double x = Math.pow(dm.widthPixels / dm.xdpi, 2);
double y = Math.pow(dm.heightPixels / dm.ydpi, 2);
double screenInches = Math.sqrt(x + y);
float tempTextSize = 0;
float statsTextSize = 0;
if(screenInches < 4)
{
tempTextSize = 48;
statsTextSize = 24;
}
else if(screenInches < 7)
{
tempTextSize = 60;
statsTextSize = 30;
}
else if(screenInches < 10)
{
tempTextSize = 72;
statsTextSize = 36;
}
else
{
tempTextSize = 120;
statsTextSize = 60;
}
currentTemp = (TextView) findViewById(R.id.currentTemp);
currentTemp.setTypeface(kfb);
currentTemp.setTextColor(Color.WHITE);
currentTemp.setTextSize(tempTextSize);
humidityText = (TextView) findViewById(R.id.humidityText);
humidityText.setTypeface(kfb);
humidityText.setTextColor(Color.WHITE);
humidityText.setTextSize(statsTextSize);
new ParseJSON().execute();
}
public static class JSONParser
{
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser()
{
}
public JSONObject getJSONFromUrl(String jsonUrl)
{
// Making HTTP request
try
{
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(jsonUrl);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
catch (UnsupportedEncodingException e)
{
e.printStackTrace();
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
is.close();
json = sb.toString();
}
catch (Exception e)
{
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try to parse the string to a JSON object
try
{
jObj = new JSONObject(json);
}
catch (JSONException e)
{
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
public static class ParseJSON extends AsyncTask<Void,Void,ArrayList>
{
@Override
protected void onPreExecute()
{
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected ArrayList doInBackground(Void... params)
{
JSONParser jParser = new JSONParser();
// get json from url here
JSONObject json = jParser.getJSONFromUrl(url);
try
{
JSONObject data = new JSONObject(json.getString("data"));
JSONArray currentConditions = data.getJSONArray("current_condition");
JSONArray weather = data.getJSONArray("weather");
JSONObject temp = currentConditions.getJSONObject(0);
fahr = temp.getString("temp_F");
humidity = temp.getString("humidity");
values.add(fahr);
values.add(humidity);
}
catch(Exception e)
{
e.getMessage().toString();
}
// return fahr;
return values;
}
@Override
protected void onPostExecute(ArrayList result)
{
// TODO Auto-generated method stub
super.onPostExecute(result);
currentTemp.setText(result.get(0).toString() + "\u00B0F");
humidityText.setText("Humidity: " + result.get(1).toString() + "%");
}
}
}
问题在于,Weather类中的List仅初始化一次,因为它是静态的。
这是发生了什么:
您从新的URL响应中解析新的JSON。 解析器将两个元素添加到ArrayList中。 现在,您可以检查其中是否包含4个元素。
因为您是这样阅读列表的:
currentTemp.setText(result.get(0).toString() + "\u00B0F");
humidityText.setText("Humidity: " + result.get(1).toString() + "%");
只有前两个元素将被设置为TextViews,即来自第一个URL的值。
您可以通过在onCreate()中创建ArrayList来避免这种情况。 或不要使AsyncTask成为静态内部类。 这样,您不必将Activity的字段声明为静态。
尝试删除您的第一个活动的SetonEditorActionListener部分,看看它是否正常工作。 您的代码似乎不错。 尝试打印传递到第二个活动的值的日志。 有一个小问题,我认为您应该在onPostExecute方法中解析JSON,因为如果发生JSONException,则可能会出现Window Leak错误。希望它会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.