繁体   English   中英

Android JSON问题

[英]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仅初始化一次,因为它是静态的。

这是发生了什么:

  1. 您可以通过Intent将第一个网址传递给第二个Activity。
  2. Activity和静态ArrayList将被实例化。
  3. 您的解析器填充ArrayList(2个元素)
  4. 您回到第一个活动
  5. 一个新的网址将传递给第二个活动
  6. ArrayList不会被新实例化!

您从新的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM