skip to Main Content

I’m new to android app development and am following a weather app made in a textbook, and the app opens in the emulator, but when I input a city to display the weather the app closes and gives me the following error:

" java.lang.NullPointerException: Attempt to invoke virtual method ‘org.json.JSONArray org.json.JSONObject.getJSONArray(java.lang.String)’ on a null object reference"

public class MainActivity extends AppCompatActivity {

    private final List<Weather> weatherList = new ArrayList<>();

    private WeatherArrayAdapter weatherArrayAdapter;
    private ListView weatherListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        findViewById(R.id.toolbar);
        setSupportActionBar();

        weatherListView = findViewById(R.id.weatherListView);
        weatherArrayAdapter = new WeatherArrayAdapter(this,weatherList);
        weatherListView.setAdapter(weatherArrayAdapter);

        FloatingActionButton fab =
                findViewById(R.id.fab);
        fab.setOnClickListener((view) -> {
            EditText locationEditText =
                    findViewById(R.id.locationEditText);
            URL url = createURL(locationEditText.getText().toString());

            if (url != null) {
                dismissKeyboard(locationEditText);
                GetWeatherTask getLocalWeatherTask = new GetWeatherTask();
                getLocalWeatherTask.execute(url);
            }
            else {
                Snackbar.make(findViewById(R.id.coordinatorLayout),
                        "Invalid URL", Snackbar.LENGTH_LONG).show();
            }

        });
    }

    private void setSupportActionBar() {
    }

    private void dismissKeyboard(View view) {
        InputMethodManager imm = (InputMethodManager)  getSystemService(
                Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(view.getWindowToken(),0);

    }

    private URL createURL(String city) {
        String apiKey = "()";
        String baseURL = "http://api.openweathermap.org/data/2.5/forecast/daily?q=";


        try {

            String urlString = baseURL + URLEncoder.encode(city,"UTF-8") +
                    "()" + apiKey;
            return new URL(urlString);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 
     */
    @SuppressWarnings("deprecation")
    @SuppressLint("StaticFieldLeak")
    private class GetWeatherTask
        extends AsyncTask<URL, Void, JSONObject> {

        @Override
        protected JSONObject doInBackground(URL... params) {
            HttpURLConnection connection = null;


            try {
                connection = (HttpURLConnection) params[0].openConnection();
                int response = connection.getResponseCode();

                if (response == HttpURLConnection.HTTP_OK) {
                    StringBuilder builder = new StringBuilder();

                    try (BufferedReader reader = new BufferedReader(
                            new InputStreamReader(connection.getInputStream()))) {

                        String line;

                        while ((line = reader.readLine()) != null) {
                            builder.append(line);
                        }
                    }
                    catch (IOException e) {
                        Snackbar.make(findViewById(R.id.coordinatorLayout),
                                "Unable to read weather data", Snackbar.LENGTH_LONG).show();
                        e.printStackTrace();
                    }
                    return new JSONObject(builder.toString());
                }
                else {
                    Snackbar.make(findViewById(R.id.coordinatorLayout),
                            "Unable to connect to OpenWeatherMap.org", Snackbar.LENGTH_LONG).show();


            }
        }
        catch (Exception e) {
            Snackbar.make(findViewById(R.id.coordinatorLayout),
                    "Unable to connect to OpenWeather.org", Snackbar.LENGTH_LONG).show();
            e.printStackTrace();
        }
        finally {
                assert connection != null;
                connection.disconnect();
        }
        return null;
    }


    @Override
    protected void onPostExecute(JSONObject weather) {
        convertJSONtoArrayList(weather);
        weatherArrayAdapter.notifyDataSetChanged();
        weatherListView.smoothScrollToPosition(0);
    }
}

private void convertJSONtoArrayList(JSONObject forecast) {
    weatherList.clear();

    try {
        JSONArray list = forecast.getJSONArray("list");

        for (int i = 0; i < list.length(); ++i) {
            JSONObject day = list.getJSONObject(i);

            JSONObject temperatures = day.getJSONObject("temp");

            JSONObject weather =
                    day.getJSONArray("weather").getJSONObject(0);

            weatherList.add(new Weather(
                    day.getLong("dt"),
                    temperatures.getDouble("min"),
                    temperatures.getDouble("max"),
                    day.getDouble("humidity"),
                    weather.getString("description"),
                    weather.getString("icon")));
        }
    }
    catch (JSONException e) {
        e.printStackTrace();
    }
 }

}

I tried some of the recommended fixes that appear as the yellow lines in the editor but it still doesn’t work. Any help is appreciated.

2

Answers


  1. You are calling getJSONArray(java.lang.String) on a null object. It means that one of these two objects is null:

    JSONArray list = forecast.getJSONArray("list");
    day.getJSONArray("weather").getJSONObject(0);
    

    Can you double check them?

    Login or Signup to reply.
  2. inside your convertJSONtoArrayList(JSONObject forecast) method, add a null check like this

    if (forecast == null) {
        return;
    }
    weatherList.clear();
    

    this will immediately return null and prevent app from crashing.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search