title: Android BaseAdapter notifyDataSetChanged() sometimes works and sometimes doesn't
body: <p>Before I begin, I checked all the other answers in Stackoverflow.com.
  Sorry for bringing up another same old notifyDataSetChanged()-doesn't-work stuff.</p>
  
  <p>If I find an answer, I will answer to my own question.</p>
  
  <p>Hi, I am having difficulty in using ListViewAdapter which extends BaseAdapter as you see below.
  There are a lot of talks on this issue in Stackoverflow.com or many other blogs.
  Solution seems to converge to saying </p>
  
  <p>1) Don't forget to set setListAdapter.
  2) Use notifyDataSetChanged() when new data is added. (Some say use notifyDataSetInvalidate ... )</p>
  
  <p>The tutorial I have been studying is </p>
  
  <p><a href="http://adilsoomro.blogspot.kr/2012/12/android-listview-with-speech-bubble.html" rel="nofollow">http://adilsoomro.blogspot.kr/2012/12/android-listview-with-speech-bubble.html</a></p>
  
  <p>.</p>
  
  <p>The problem is sometimes it works very well but it sometimes it doesn't. </p>
  
  <p>There is no pattern.</p>
  
  <p>Since the messages are transmitted from other system, I thought it was due to network problem.
  But all the messages were seamlessly coming into my app.</p>
  
  <p>The reason I have not used ArrayList instance on ListViewActivity is that
  from certain point of system operations occur a case where ArrayList instance
  within ListViewAdapter fails to sync with the arrayList on ListViewActivity.
  And I've confirmed that there starts to exist a moment where 
  some messages are put into list A(within ListViewActivty) and other messages into
  list B(within ListViewAdapter but I am not sure if this is really the case). 
  That's why I removed the arraylist within ListViewActivty.</p>
  
  <p>Update is done within onPostExecute part of AsyncTask, not using runUiThread
  (There was no difference bewteen using runUiThread and not).</p>
  
  <p>And I've found when list view is not updated, getView() was not called either,
  even though message list in adapter had added data and getCount() returns
  exact number of refreshed data size.</p>
  
  <p>I doubt the operation inside onPostExecute is once in a while blocked by
  some unknown process. </p>
  
  <p></p>
  
  <p>When I give UI event( for example, entering text ) on my app, 
  it gives a late refresh of the added data on screen which should 
  have been done when addNewMessage() was called().</p>
  
  <p>======================================================================= </p>
  
  <h1>1. AsycTask in which addNewMessage() is called  ( a part of ListViewActivity.java )</h1>
  
  <pre><code>private class RefreshListView extends AsyncTask&lt;Argument, String, Argument&gt;
  {
  @Override
  protected Argument doInBackground(Argument... _args) 
  { 
       Argument result = new Argument();
  
       result.setMessageString( _args[0].getMessageString() );
       result.setIsMine( _args[0].getIsMine() );
  
       return result;
  }
  
        @Override
  public void onProgressUpdate(String... v) 
  { 
  
  }
  
  @Override
  protected void onPostExecute(Argument _arg ) 
  {
      addNewMessage(new Message( _arg.getMessageString(), _arg.getIsMine() ) );  
  }
  } 
  </code></pre>
  
  <p>======================================================================= </p>
  
  <h1>2. A point where notifyDataSetChanged() is called. ( a part of ListViewActivity.java )</h1>
  
  <pre><code>public void addNewMessage( final Message _message )
  {
      adapter.add( _message ); 
      adapter.notifyDataSetChanged();
      getListView().setSelection( adapter.observeMessageList().size() - 1 );
  }
  </code></pre>
  
  <p>======================================================================= </p>
  
  <h1>3. ListViewActivity setting ListViewAdapter as an observer</h1>
  
  <pre><code>public void onCreate( Bundle savedInstanceState ) 
  {
      adapter = new ListViewAdapter( this );
      this.setListAdapter( adapter );
  }
  </code></pre>
  
  <p>======================================================================= </p>
  
  <h1>4. ListViewAdapter.java which has actual arrayList that stores data item</h1>
  
  <pre><code>import java.util.ArrayList;
  import java.util.Iterator;
  
  import com.test.R;
  
  import android.content.Context;
  import android.util.Log;
  import android.view.Gravity;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.BaseAdapter;
  import android.widget.LinearLayout.LayoutParams;
  import android.widget.TextView;
  
  // http://stackoverflow.com/questions/3669325/notifydatasetchanged-example
  public class ListViewAdapter extends BaseAdapter
  {
  private Context mContext;
  
  public static ArrayList&lt;com.test.Message&gt; mMessages = new ArrayList&lt;com.test.Message&gt;();
  
  public ListViewAdapter(Context context ) 
  {
       super();
  
       this.mContext = context;
  }
  
  public void clearMessages()
  {
      ListViewAdapter.mMessages.clear();
  }
  
  public void add( Message  _message )
  {
      ListViewAdapter.mMessages.add( _message );
  }
  
  public ArrayList&lt;com.test.Message&gt; observeMessageList()
  {
       return ListViewAdapter.mMessages;
  }
  
  @Override
  public int getCount() 
  { 
      return mMessages.size();
  } 
  
  
  @Override
  public Object getItem( int position ) 
  {       
      return mMessages.get( position );
  }
  
  
  @Override
  public View getView( int position, View convertView, ViewGroup parent ) 
  {
      com.test.Message message = (com.test.Message) this.getItem(position);
  
      ViewHolder holder; 
  
      if ( convertView == null )
      {
          holder = new ViewHolder();
  
          convertView = LayoutInflater.from(mContext).inflate(R.layout.sms_row, parent, false);
  
          holder.message = (TextView) convertView.findViewById(R.id.message_text);
  
          convertView.setTag(holder);
      }
      else
      {
          holder = (ViewHolder) convertView.getTag();
      }
  
      holder.message.setText( message.getMessage() );
  
      LayoutParams lp = (LayoutParams) holder.message.getLayoutParams();
  
      // check if it is a status message then remove background, and change text color.
      if ( message.isStatusMessage() )
      {
          holder.message.setBackgroundDrawable(null);
  
          lp.gravity = Gravity.LEFT;
  
          // holder.message.setTextColor( R.color.textFieldColor );
      }
      else
      {       
          // Check whether message is mine to show green background and align to right
          if ( message.isMine() )
          {
              holder.message.setBackgroundResource(R.drawable.speech_bubble_green);
              lp.gravity = Gravity.RIGHT;
          }
          // If not mine then it is from sender to show orange background and align to left
          else
          {
              holder.message.setBackgroundResource(R.drawable.speech_bubble_orange);
              lp.gravity = Gravity.LEFT;
          }
  
          holder.message.setLayoutParams(lp);
  
          // holder.message.setTextColor( R.color.textColor );    
      }
  
      return convertView;
  }
  
  public static class ViewHolder
  {
      TextView message;
  }
  
  @Override
  // http://stackoverflow.com/questions/6711592/what-is-the-intent-of-the-methods-getitem-and-getitemid-in-the-android-class-bas
  public long getItemId(int position) 
  {
      // Unimplemented, because we aren't using Sqlite.
  
      // http://stackoverflow.com/questions/24223393/android-listview-custom-adapter-getview-never-called-up
      return 0;
      // return position;
  }
  </code></pre>
  
  <p>}</p>