-2

I'm making an app to pull weather data from openweathermap and view it in a listview and it keeps on returning a nullpointerexception error and crashing. This happens when I try to call the setListAdapter(adapter) method. I've been trying to debug this problem on my own for a few days now but I can't seem to find the issue. I'd really appreciate any help I could get.

Here's my main activity class

public class MainActivity extends ListActivity {

    String mainUrl = "http://api.openweathermap.org/data/2.5/forecast/daily?q=";
    String accessCode = "&APPID=4907e373098f091c293b36b92d8f0886";
    List<WeatherModel> weatherlist;


    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EditText getcityview = (EditText)findViewById(R.id.City);
        Button searchButton = (Button) findViewById(R.id.search);
        searchButton.setOnClickListener(search);

    }

    public String getcity(){

        EditText getcityview = (EditText)findViewById(R.id.City);
        String Cityname = getcityview.getText().toString().trim();
        String result = deleteSpace(Cityname);
        return result;

    }

    public String deleteSpace(String city){
       int loc = city.indexOf(" ");
        if (loc != -1){
            String result = city.substring(0, loc) + city.substring(loc + 1);
            return result;
        }
        else {
            return city;
        }
    }

    public void showForecast(){
        EditText getcityview = (EditText)findViewById(R.id.City);
        if (!isEmpty(getcityview) ) {
            Log.d("Status:", "running");
           String cityName = getcity();
            String url = mainUrl + cityName + accessCode;
            JsonParser Jparser = new JsonParser();
            Jparser.execute(url);

        }
        else {
            Toast.makeText(getApplicationContext(), "No City entered", Toast.LENGTH_SHORT);
        }
    }

    private boolean isEmpty(EditText etText) {
        return etText.getText().toString().trim().length() == 0;
    }
    public View.OnClickListener search = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            showForecast();
        }
    };
    public void UpdateDisplay(){
        WeatherAdapter weatheradapter = new WeatherAdapter(this, R.layout.weather_item, weatherlist);
        setListAdapter(weatheradapter);
    }


    private class JsonParser extends  AsyncTask<String, String, JSONObject>{
        final String TAG = "JsonParser.java";

        InputStream is = null;
        JSONObject jObj = null;
        String json = "";
        HttpURLConnection UrlConnection = null;
        List<WeatherModel> weatherList;

        // make HTTP request


        @Override
        protected JSONObject doInBackground(String...params) {
            try {

                URL Url = new URL(params[0]);
                UrlConnection = (HttpURLConnection) Url.openConnection();
                UrlConnection.connect();

                is = UrlConnection.getInputStream();

            } 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(TAG, "Error converting result " + e.toString());
            }

            // try parse the string to a JSON object
            try {
                jObj = new JSONObject(json);
            } catch (JSONException e) {
                Log.e(TAG, "Error parsing data " + e.toString());
            }

            // return JSON String
            Log.d("Confirmed", "Got JSON");
            return jObj;
        }


        @Override
        protected void onPostExecute(JSONObject o) {
            super.onPostExecute(o);
            Log.d("Json:", o.toString());
            weatherList = WeatherParser.ParseFeed(o);
            UpdateDisplay();

        }


    }

}

Here's my custom adapter class

public class WeatherAdapter extends ArrayAdapter<WeatherModel> {

private Context context;
private List<WeatherModel> weatherlist;
public WeatherAdapter(Context context, int resource, List<WeatherModel> objects){
    super(context, resource, objects);
    this.context = context;

    this.weatherlist = objects;

}

@Override
public View getView(int position, View convertView, ViewGroup parent){
    LayoutInflater inflater  = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.weather_item, parent, false);

    WeatherModel weather = weatherlist.get(position);
    TextView day = (TextView) view.findViewById(R.id.day);
    TextView temperature = (TextView) view.findViewById(R.id.temperature);
    TextView description = (TextView) view.findViewById(R.id.description);

    day.setText(weather.getDate());
    temperature.setText(weather.getTemperature());
    description.setText(weather.getDescription());
    return view;


}

}

Here's my logcat

06-15 16:07:47.912 30849-30849/com.example.android.weatherforecast D/Status:: running 06-15 16:07:48.233 30849-6794/com.example.android.weatherforecast D/Confirmed: Got JSON 06-15 16:07:48.253 30849-30849/com.example.android.weatherforecast D/Json:: {"message":0.0079,"list":[{"clouds":36,"dt":1466010000,"humidity":52,"pressure":995.17,"speed":3.31,"deg":150,"weather":[{"id":802,"icon":"03d","description":"scattered clouds","main":"Clouds"}],"temp":{"morn":297.43,"min":287.68,"night":287.68,"eve":294.14,"max":297.43,"day":297.43}},{"clouds":0,"dt":14660964...... 06-15 16:07:48.253 30849-30849/com.example.android.weatherforecast D/Confirmed: JSON parsed 06-15 16:07:48.273 30849-30849/com.example.android.weatherforecast D/AndroidRuntime: Shutting down VM 06-15 16:07:48.273 30849-30849/com.example.android.weatherforecast W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x4181ada0) 06-15 16:07:48.293 30849-30849/com.example.android.weatherforecast E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.android.weatherforecast, PID: 30849 java.lang.NullPointerException at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330) at android.widget.ListView.setAdapter(ListView.java:486) at android.app.ListActivity.setListAdapter(ListActivity.java:265) at com.example.android.weatherforecast.MainActivity.UpdateDisplay(MainActivity.java:89) at com.example.android.weatherforecast.MainActivity$JsonParser.onPostExecute(MainActivity.java:156) at com.example.android.weatherforecast.MainActivity$JsonParser.onPostExecute(MainActivity.java:93) at android.os.AsyncTask.finish(AsyncTask.java:632) at android.os.AsyncTask.access$600(AsyncTask.java:177) at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:157) at android.app.ActivityThread.main(ActivityThread.java:5356) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081) at dalvik.system.NativeStart.main(Native Method)

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
majestyc54
  • 125
  • 5
  • 13

2 Answers2

2

Be aware that this here

WeatherModel weather = weatherlist.get(position);

is the reason of the exception,

you have declared

private List<WeatherModel> weatherlist;

but this is never initialized, so the object weatherlist is pointing to a null reference...

ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
1

You declared 2 List<WeatherModel> weatherlist, one in your MainActivity and the other in your JsonParser.
The weatherList in MainActivity is never assigned and that's why you get a NullPointerException.

You could remove both variables and in your JsonParser do:

@Override
protected void onPostExecute(JSONObject o) {
    super.onPostExecute(o);
    Log.d("Json:", o.toString());
    UpdateDisplay(WeatherParser.ParseFeed(o));
}

Your method UpdateDisplay could be like this:

public void UpdateDisplay(List<WeatherModel> weatherlist){
    WeatherAdapter weatheradapter = new WeatherAdapter(this, R.layout.weather_item, weatherlist);
    setListAdapter(weatheradapter);
}
Juan Cruz Soler
  • 8,172
  • 5
  • 41
  • 44