0

I am trying to parse some JSON in my app. I have an activity that the user types in their location and presses a button which opens another activity. The problem is that the app crashes when opening the second activity. I used a tutorial to figure out how to get the JSON data but can't figure out what I'm doing wrong. I'm pretty new to Android development so any ideas or help are greatly appreciated.

Here is my code:

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();
                     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);
                startActivity(weather);
            }
        });
    }
}

Weather info class:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

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.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class Weather extends WeatherLocation 
{
    TextView currentTemp;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.weather);

        currentTemp = (TextView) findViewById(R.id.currentTemp);     

        // Create instance of JSONParser
        JSONParser jParser = new JSONParser();

        // getting JSON string from URL
        System.out.println(newURL);
        JSONObject json = jParser.getJSONFromUrl(newURL);

        try
        {
            JSONObject data = new JSONObject(json.getString("data"));
            JSONArray currentConditions = data.getJSONArray("current_condition");
            JSONArray weather = data.getJSONArray("weather");

            JSONObject temp = currentConditions.getJSONObject(0);
            String fahr = temp.getString("temp_F");
            currentTemp.setText(fahr);
        }
        catch(Exception e)
        {
            e.getMessage().toString();
        }
    }

    public static class JSONParser
    {
        static InputStream is = null;
        static JSONObject jObj = null;
        static String json = "";

        // constructor
        public JSONParser()
        {

        }

        public JSONObject getJSONFromUrl(String url)
        {
            // Making HTTP request
            try
            {
                // defaultHttpClient
                DefaultHttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(url);

                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;
        }
    }
}

Errors:

10-14 13:11:28.523: E/AndroidRuntime(6583): FATAL EXCEPTION: main
10-14 13:11:28.523: E/AndroidRuntime(6583): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kentuckyfarmbureau.kyfb/com.kentuckyfarmbureau.kyfb.Weather}: java.lang.NullPointerException
10-14 13:11:28.523: E/AndroidRuntime(6583):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at android.os.Looper.loop(Looper.java:137)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at android.app.ActivityThread.main(ActivityThread.java:5103)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at java.lang.reflect.Method.invokeNative(Native Method)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at java.lang.reflect.Method.invoke(Method.java:525)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at dalvik.system.NativeStart.main(Native Method)
10-14 13:11:28.523: E/AndroidRuntime(6583): Caused by: java.lang.NullPointerException
10-14 13:11:28.523: E/AndroidRuntime(6583):     at com.android.internal.os.LoggingPrintStream.println(LoggingPrintStream.java:298)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at com.kentuckyfarmbureau.kyfb.Weather.onCreate(Weather.java:42)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at android.app.Activity.performCreate(Activity.java:5133)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
10-14 13:11:28.523: E/AndroidRuntime(6583):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
10-14 13:11:28.523: E/AndroidRuntime(6583):     ... 11 more

EDIT: I have edited the code in Weather.java (the second activity) to include this:

Intent intent = getIntent();
        String url = intent.getStringExtra("INTENT_KEY_URL");

System.out.println(url);
        JSONObject json = jParser.getJSONFromUrl(url);
4

2 回答 2

2

您正在 ui 线程上运行与网络相关的操作。

JSONObject json = jParser.getJSONFromUrl(newURL);

在 JsonParser 你有

HttpResponse httpResponse = httpClient.execute(httpPost);

使用threadAsyncTask

class TheTask extends AsyncTask<Void,Void,Void>
  {

    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);



    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();

    }

    @Override
    protected Void doInBackground(Void... params) {
            // get json from url here
            getJSONFromUrl(String url);
        return null;
    }

  }

调用new TheTask().execute()

http://developer.android.com/reference/android/os/AsyncTask.html

于 2013-10-14T16:47:30.987 回答
0

首先,您必须将您的“网址”发送到第二个活动。为此,您可以使用带有额外参数的 Intent

喜欢以下

    Intent weather = new Intent(WeatherLocation.this, Weather.class);
    weather .putExtra("INTENT_KEY_URL",newURL );
    startActivity(weather);

在您的第二个活动中,您可以将 URL 放入您的 onCreate 方法中,如下所示

    Intent intent =getIntent();
    String url =intent.getStringExtra("INTENT_KEY_URL");

然后你可以用它来查询你的 json 数据。

如果您可以发布此错误的堆栈跟踪,这将非常有帮助。

于 2013-10-14T16:58:42.157 回答