title: My Custom CursorAdapter doesn't update my ListView
body: <p>I'm having troubles with my Custom <code>CursorAdapter</code> and my <code>ListView</code>, the fact is, I can save data in my sqlite Database in my custom <code>ContentProvider</code> but my <code>ListView</code> is not populated.</p>
  
  <p>I know DB Operations are heavy long operations, therefore I do it in another thread and furthermore <code>CursorLoader</code> is a subclass of <code>AsyncTaskLoader</code>, so it should be prepared for that.</p>
  
  <p>With <code>SimpleCursorAdapter</code> works fine but with this Custom <code>CursorAdapter</code> not.</p>
  
  <p>Can anyone tell me what is wrong and how could I solve it?</p>
  
  <p>Thanks in advance.</p>
  
  <p>My code is the following</p>
  
  <pre><code>public class TextNoteAdapter extends CursorAdapter {
  
      /*********** Declare Used Variables *********/
  
      private Cursor                 mCursor;
      private Context                mContext;         
      private static  LayoutInflater mInflater=null;
  
      /*************  TextNoteAdapter Constructor *****************/
      public TextNoteAdapter (Context context, Cursor cursor, int flags) {
          super(context, cursor,flags);
  
          mInflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
          mContext  = context;
          mCursor   = cursor;                           
      } 
  
      @Override
      public View newView(Context context, Cursor cursor, ViewGroup parent) {
  
          //LayoutInflater inflater = LayoutInflater.from(parent.getContext());
          View view = mInflater.inflate(R.layout.textnote_info, parent, false);
          ViewHolder holder = new ViewHolder();
  
          holder.note_name               = (TextView)view.findViewById(R.id.note_name);
          holder.creation_date           = (TextView)view.findViewById(R.id.creation_date);
          holder.modification_date       = (TextView)view.findViewById(R.id.modification_date);
          holder.label_creation_date     = (TextView)view.findViewById(R.id.label_creation_date);
          holder.label_modification_date = (TextView)view.findViewById(R.id.label_modification_date);
  
  
          view.setTag(holder);
  
          return view;
      }    
  
       @Override
       public void bindView(View view, Context context, Cursor cursor) {
           // here we are setting our data what means, take the data from the cursor and put it in views
           View vi = view;
           ViewHolder holder = (ViewHolder)view.getTag();
  
           if(view==null){                  
               /****** Inflate textnote_info.xml file for each row ( Defined below ) *******/
               vi = mInflater.inflate(R.layout.textnote_info, null);
  
              /************  Set holder with LayoutInflater ************/
               vi.setTag( holder );
  
           } else 
               holder=(ViewHolder)vi.getTag();                          
  
  
           /************  Set Model values in Holder elements ***********/
           holder.note_name.setText(cursor.getString(cursor.getColumnIndex(TextNotesDb.KEY_NOTE_NAME)));
           holder.creation_date.setText(cursor.getString(cursor.getColumnIndex(TextNotesDb.KEY_CREATION_DATE)));
           holder.modification_date.setText(cursor.getString(cursor.getColumnIndex(TextNotesDb.KEY_MODIFICATION_DATE)));
           holder.label_creation_date.setText(Constants.LABEL_CREATION_DATE);
           holder.label_modification_date.setText(Constants.LABEL_MODIFICATION_DATE);
  
       }         
  
  
       @Override
       protected void onContentChanged() {
            // TODO Auto-generated method stub
            super.onContentChanged();
            notifyDataSetChanged();
       }         
  
  
       /********* Create a holder Class to contain inflated xml file elements *********/
       public static class ViewHolder{
  
           public TextView note_name;
           public TextView creation_date;
           public TextView modification_date;
           public TextView label_creation_date;
           public TextView label_modification_date;
  
       }
  
  
  
   }
  </code></pre>
  
  <p>And here my MainActivity</p>
  
  <pre><code>import android.app.Activity;
  import android.app.LoaderManager;
  import android.content.CursorLoader;
  import android.content.Intent;
  import android.content.Loader;
  import android.database.Cursor;
  import android.os.Bundle;
  import android.os.Handler;
  import android.util.Log;
  import android.view.Menu;
  import android.view.View;
  import android.widget.AdapterView;
  import android.widget.AdapterView.OnItemClickListener;
  import android.widget.Button;
  import android.widget.CursorAdapter;
  import android.widget.ListView;
  import android.widget.Toast;
  
  public class MainActivity extends Activity implements LoaderManager.LoaderCallbacks&lt;Cursor&gt;{
  
  
      private Cursor              cursor;
      private Button              addButton;
      private ListView            listView;
      private TextNoteAdapter     dataAdapter;
  
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);     
  
          displayListView(); 
  
          addButton = (Button)findViewById(R.id.add_textnote);
  
          addButton.setOnClickListener(new View.OnClickListener() {
  
              @Override
              public void onClick(View v) {
                  // starts a new Intent to add a Note
                  Intent intent = new Intent(getBaseContext(), TextNoteEdit.class);
                  Bundle bundle = new Bundle();
                  bundle.putString("mode", "add");
                  intent.putExtras(bundle);
                  startActivity(intent);
              }
          });
  
      }
  
      @Override
      protected void onResume() {
          super.onResume();
          Log.i("TAG", "MainActivity:: onResume");
          /** Starts a new or restarts an existing Loader in this manager **/
          getLoaderManager().restartLoader(0, null, this);
      }
  
  
      private void displayListView() {
  
      // That ensures a loader is initialized and active.
      // If the loader specified by the ID already exists, the last created loader is reused.
      // else  initLoader() triggers the LoaderManager.LoaderCallbacks method onCreateLoader().
      // This is where you implement the code to instantiate and return a new loader
  
      getLoaderManager().initLoader(0, null, this);        
  
  
      // We get ListView from Layout and initialize
      listView = (ListView) findViewById(R.id.textnote_list);
  
      // DB takes long, therefore this operation should take place in a new thread!                     
      new Handler().post(new Runnable() {
                  @Override
                  public void run() {
                      dataAdapter = new TextNoteAdapter(MainActivity.this, null, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
                      listView.setAdapter(dataAdapter);
                      Log.i("TAG", "MainActivity:: Handler... Run()");                       
                  }
              });               
  
      listView.setOnItemClickListener(new OnItemClickListener() {
              @Override
              public void onItemClick(AdapterView&lt;?&gt; listView, View view, int position, long id) {
  
                  /** Get the cursor, positioned to the corresponding row in the result set **/
                  Cursor cursor = (Cursor) listView.getItemAtPosition(position);               
  
                  // display the selected note
                  String noteName = cursor.getString(cursor.getColumnIndexOrThrow(TextNotesDb.KEY_NOTE_NAME));
  
                  Toast.makeText(getApplicationContext(), noteName, Toast.LENGTH_SHORT).show();
  
                  String rowId = cursor.getString(cursor.getColumnIndexOrThrow(TextNotesDb.KEY_ROWID));
  
  
                  // starts a new Intent to update/delete a Textnote
                  // pass in row Id to create the Content URI for a single row
                  Intent intent = new Intent(getBaseContext(), TextNoteEdit.class);
                  Bundle bundle = new Bundle();
                  bundle.putString("mode", "update");
                  bundle.putString("rowId", rowId);
                  intent.putExtras(bundle);
                  startActivityForResult(intent, 1);
  
              }
          });
  
      }    
  
      /** This is called when a new Loader needs to be created.**/
      @Override
      public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
          Log.i("TAG", "MainActivity:: onCreateLoader");
          String[] projection = { 
                              TextNotesDb.KEY_ROWID,
                              TextNotesDb.KEY_GUID,
                              TextNotesDb.KEY_NOTE_NAME,
                              TextNotesDb.KEY_NOTE,
                              TextNotesDb.KEY_CREATION_DATE,
                              TextNotesDb.KEY_MODIFICATION_DATE
                             };
       CursorLoader cursorLoader = new CursorLoader(this, MyContentProvider.CONTENT_URI, projection, null, null, null);
  
          return cursorLoader;
      }
  
      @Override
      public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor data) {
          // Swap the new cursor in.  (The framework will take care of closing the
          // old cursor once we return.)       
          dataAdapter.swapCursor(data);
      }
  
      @Override
      public void onLoaderReset(Loader&lt;Cursor&gt; loader) {
          // This is called when the last Cursor provided to onLoadFinished()
          // above is about to be closed.  We need to make sure we are no
          // longer using it.
          dataAdapter.swapCursor(null);
      }
  
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          getMenuInflater().inflate(R.menu.activity_main, menu);
          return true;
      }
  
  
  }
  </code></pre>