0

我有一项活动,允许用户输入邮政编码或城市以获取天气信息。然后他们被带到另一个显示信息的活动。这可以正常工作,除非您返回第一个活动以输入不同的邮政编码或城市。当您放入另一个位置并转到第二个活动以显示新位置的天气信息时,它会改为提取第一个位置的信息。例如,我输入一个位置,然后进入第二个活动,它显示温度为 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() + "%");
        }
      }
}
4

2 回答 2

1

问题是您的 Weather 类中的 List 只初始化一次,因为它是静态的。

这就是发生的事情:

  1. 您通过 Intent 将第一个 url 传递给第二个 Activity。
  2. Activity 和静态 ArrayList 将被实例化。
  3. 您的解析器填充 ArrayList(2 个元素)
  4. 你回到第一个Activity
  5. 一个新的 Url 将传递给第二个 Activity
  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 的字段声明为静态的。

于 2013-10-16T14:22:23.387 回答
0

尝试删除第一个活动的 SetonEditorActionListener 部分,看看它是否正常工作。你的代码看起来不错。尝试打印传递给第二个活动的值的日志。有一个小问题,我认为你应该在 onPostExecute 方法中解析 JSON,因为如果发生 JSONException,你可能会得到 Window Leak 错误。希望它有帮助。

于 2013-10-16T14:05:19.840 回答