title: Android: CustomAdapter ArrayList data Nullpointerexception
body: <p>I have been learning android app development for two weeks and really got stuck here. I attempted to retrieve hourly-forecast data (which is in JSON format) from OpenWeatherMap API in a ArrayList that can be fitted into a Listview with three elements by a customised Adapter. If the user enter a city name, s/he should be able to see a list - weather information per hour occupies one line of the list. The data retrieval process was done by AsyncTask.</p>
  
  <p>However after hitting the "find sun" button, the app crashed and the logcat kept showing me:</p>
  
  <pre><code>&gt;FATAL EXCEPTION: main
  &gt;java.lang.NullPointerException: Attempt to invoke virtual method 'RowAdapter.clear()' on a null object reference
  &gt;at MainActivity$WeatherDownloadTask.onPostExecute(MainActivity.java:78)
  &gt;at MainActivity$WeatherDownloadTask.onPostExecute(MainActivity.java:61)
  &gt;at android.os.AsyncTask.finish(AsyncTask.java:636)
  &gt;at android.os.AsyncTask.access$500(AsyncTask.java:177)
  &gt;at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653)
  &gt;at android.os.Handler.dispatchMessage(Handler.java:102)
  &gt;at android.os.Looper.loop(Looper.java:135)
  &gt;at android.app.ActivityThread.main(ActivityThread.java:5254)
  &gt;at java.lang.reflect.Method.invoke(Native Method)
  &gt;at java.lang.reflect.Method.invoke(Method.java:372)
  &gt;at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
  &gt;at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
  
  Line 61 is    public class WeatherDownloadTask extends AsyncTask&lt;String, Void, ArrayList&lt;Weather&gt;&gt; "\n"
  Line 78 is    for (Weather w : weather) {rowAdapter.add(w);}
  </code></pre>
  
  <p>This is my Main Activity java file:</p>
  
  <pre><code>public class MainActivity extends AppCompatActivity {
      private static final String TAG = "MainActivity";
      private RowAdapter rowAdapter;
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  
      ArrayList&lt;Weather&gt; data = new ArrayList&lt;Weather&gt;();
      ListView listv = (ListView) findViewById(R.id.listv);
      RowAdapter rowAdapter = new RowAdapter(MainActivity.this, R.layout.weather_item, data);
      listv.setAdapter(rowAdapter);
  }
  
  public void handleClick(View v) {
      Log.v(TAG, "Search Button handled");
      EditText text = (EditText) findViewById(R.id.cityname);
      String searchTerm = text.getText().toString();
  
      WeatherDownloadTask task = new WeatherDownloadTask();
      task.execute(searchTerm);
  }
  
  public class WeatherDownloadTask extends AsyncTask&lt;String, Void, ArrayList&lt;Weather&gt;&gt; {
  
      @Override
      protected ArrayList&lt;Weather&gt; doInBackground(String... params) {
          try {
              ArrayList&lt;Weather&gt; data = WeatherDownloader.downloadWeather(params[0]);
              Log.d(TAG, data.toString());
              return data;
          } catch (JSONException e) {
              return null;
          }
      }
  
      @Override
      protected void onPostExecute(ArrayList&lt;Weather&gt; weather) {
              super.onPostExecute(weather);
              rowAdapter.clear();
              for (Weather w : weather) {
                  rowAdapter.add(w);
              }
          }
      }
  }
  </code></pre>
  
  <p>This is the code to download data from the API:</p>
  
  <pre><code>public class WeatherDownloader {
  private static String BASE_URL = "http://api.openweathermap.org/data/2.5/weather?q=";
  private static String IMG_URL = "http://openweathermap.org/img/w/";
  
  // returns ArrayList of Weather, rather than String[]
  public static ArrayList&lt;Weather&gt; downloadWeather(String location) throws JSONException {
      HttpURLConnection con = null;
      ArrayList&lt;Weather&gt; weather = null;
      BufferedReader reader = null;
  
      try {
          con = (HttpURLConnection) (new URL(BASE_URL + location + "&amp;units=metric" +
                  "&amp;APPID=" + BuildConfig.OPEN_WEATHER_MAP_API_KEY)).openConnection();
          con.setRequestMethod("GET");
          con.setDoInput(true);
          con.setDoOutput(true);
          con.connect();
  
          StringBuffer buffer = new StringBuffer();
          InputStream inputStream = con.getInputStream();
          if (inputStream == null) return null;
          reader = new BufferedReader(new InputStreamReader(inputStream));
  
          String line = reader.readLine();
          while (line != null) {
              buffer.append(line + "\n");
              line = reader.readLine();
          }
  
          if (buffer.length() == 0) {
              return null;
          }
          String results = buffer.toString();
  
          weather = parseWeatherJSON(results);
          if (weather == null) weather = new ArrayList&lt;Weather&gt;();
      } catch (IOException e) {
          return null;
      } finally {
          if (con != null) {
              con.disconnect();
          }
          if (reader != null) {
              try {
                  reader.close();
              } catch (IOException e) {
              }
          }
      }
      return weather;
  }
  
  
  /**
   * Parses a JSON String into a list of Weather objects
   */
  public static ArrayList&lt;Weather&gt; parseWeatherJSON(String json) throws JSONException {
      ArrayList&lt;Weather&gt; weather = new ArrayList&lt;Weather&gt;();
      JSONObject jsonObject = new JSONObject(json);
      Weather item = new Weather();
  
      JSONArray JSONArray_weather = jsonObject.getJSONArray("weather");
  
      for (int i = 0; i &lt; JSONArray_weather.length(); i++) {
          JSONObject JSONObject_weather = JSONArray_weather.getJSONObject(i);
          item.setSun(JSONObject_weather.getString("main"));// get the weather description
  
          DateFormat df = DateFormat.getDateTimeInstance();
          String timestr = df.format(new Date(jsonObject.getLong("dt") * 1000));
          item.setTime(timestr); // get the time;
  
          // key = "main"
          JSONObject JSONObject_main = jsonObject.getJSONObject("main");
          item.setTemperature(JSONObject_main.getDouble("temp")); // get the temperature;
  
          weather.add(item);
          }
      return weather;
      }
  }
  </code></pre>
  
  <p>This is the Adapter class:</p>
  
  <pre><code>public class   RowAdapter extends ArrayAdapter&lt;Weather&gt; {
  
  private final Context context;
  private final ArrayList&lt;Weather&gt; data;
  private final int resource;
  
  // a constructor
  public RowAdapter(Context context, int resource, ArrayList&lt;Weather&gt; data) {
      super(context, resource, data);
      this.context = context;
      this.data = data;
      this.resource = resource;
  }
  
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
      View row;
      row = convertView;
      ViewHolder holder = null;
  
      if (convertView == null) {
          LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          row = inflater.inflate(R.layout.weather_item,parent,false);
  
      // initialize the components
  
          holder.textView1 = (TextView)row.findViewById(R.id.sun);
          holder.textView2 = (TextView) row.findViewById(R.id.time);
          holder.textView3 = (TextView) row.findViewById(R.id.temp);
          row.setTag(holder);
      }
      else {
          holder = (ViewHolder)row.getTag();
      }
  
      Weather weather = data.get(position);
  
      holder.textView1.setText(weather.getSun());
      holder.textView2.setText(weather.getTime());
      holder.textView3.setText(String.valueOf(weather.getTemperature()));
      return row;
  }
  static class ViewHolder
  {
      TextView textView1;
      TextView textView2;
      TextView textView3;
  }
  }
  </code></pre>
  
  <p>The Main Activity xml file:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;RelativeLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:id="@+id/mainactivity"
      android:padding="16dp"
      android:orientation="vertical"
      tools:context=".MainActivity"
      android:weightSum="1"&gt;
  
  &lt;EditText
      android:id="@+id/cityname"
      android:layout_width="214dp"
      android:layout_height="wrap_content"
      android:drawableLeft="@android:drawable/ic_menu_search"
      android:inputType="text"
      android:imeOptions="actionDone"
      android:hint="City..."
      android:layout_alignParentTop="true"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true" /&gt;
  
  &lt;Button
      android:id="@+id/searchbtn"
      android:layout_width="wrap_content"
      android:layout_height="50dp"
      android:text="Find Sun"
      android:textAllCaps="false"
      android:layout_gravity="right"
      android:layout_alignParentTop="true"
      android:layout_alignParentRight="true"
      android:layout_alignParentEnd="true"
      android:onClick="handleClick"/&gt;
  
  &lt;TextView
      android:id="@+id/sunornot"
      android:layout_width="171dp"
      android:layout_height="70dp"
      android:text = "Will there be sun?"
      android:textSize="20dp"
      android:layout_gravity="right"
      android:layout_weight="0.22"
      android:layout_below="@+id/cityname"
      android:layout_alignParentRight="true"
      android:layout_marginLeft="30dp"
      android:layout_marginTop="20dp"
      android:layout_alignParentEnd="true"
      android:layout_toRightOf="@+id/weather_icon"
      android:layout_toEndOf="@+id/weather_icon" /&gt;
  
  &lt;ImageView
      android:id="@+id/weather_icon"
      android:layout_width="65dp"
      android:layout_height="65dp"
      android:layout_above="@+id/listv"
      android:layout_alignParentLeft="true"
      android:layout_alignParentStart="true" /&gt;
  
  &lt;ListView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:id="@+id/listv"
      android:layout_alignParentBottom="true"
      android:layout_below="@+id/sunornot" /&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>I am totally new to app development, I know there might be many stupid mistakes. But I even don't know how to debug properly. It will be very kind of you to give me some suggestions. All help are greatly appreciated!</p>