NullPointerException en onLoaderFinished usando SimpleCursorAdapter

He cambiado de un ResourceCursorAdapter donde utilicé newView y bindView a un SimpleCursorAdapter donde estoy utilizando solamente el método getView .

Ahora tengo un error en onLoaderFinished . Aunque me da NullPointerException en adapter.swapCursor(cursor) tanto mi adaptador y el objeto cursor no son nulos . Voy a publicar todo mi código a continuación. Cualquier ayuda es muy apreciada (no tengo mucho pelo a la izquierda para sacar).

 import android.annotation.SuppressLint; import android.content.Context; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.widget.ResourceCursorAdapter; import android.util.Log; import android.util.SparseBooleanArray; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.view.Window; import android.widget.CheckBox; import android.widget.ListView; import android.widget.TextView; public class ContactSelect extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor> { private static final int LOADER_ID = 1; private MyAdapter adapter; private ListView list; private View row; private SparseBooleanArray checkedState = new SparseBooleanArray(); @SuppressLint({ "NewApi", "NewApi" }) @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); setContentView(R.layout.activity_contact_select); adapter = new MyAdapter(this, R.layout.contacts_select_row, null, null, null, 0); getSupportLoaderManager().initLoader(LOADER_ID, null, this); list = (ListView)findViewById(R.id.list); list.setAdapter(adapter); list.setEmptyView(findViewById(R.id.empty)); } @SuppressLint("NewApi") public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { final String projection[] = new String[]{ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME}; final Uri uri = ContactsContract.Contacts.CONTENT_URI; final String selection = ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1" + " AND " + ContactsContract.Contacts.IN_VISIBLE_GROUP + " =1"; final String order = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"; final CursorLoader loader = new CursorLoader(this, uri, projection, selection, null, order); return loader; } public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { for(int i=0;i<cursor.getCount();i++){ checkedState.put(i, false); } adapter.swapCursor(cursor); } public void onLoaderReset(Loader<Cursor> loader) { adapter.swapCursor(null); } private class MyAdapter extends SimpleCursorAdapter implements OnClickListener{ private CheckBox markedBox; private TextView familyText; private Context context; private Cursor cursor; public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) { super(context, layout, c, from, to, flags); this.context = context; this.cursor = getCursor(); } @Override public View getView(int position, View view, ViewGroup group) { final LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); row = li.inflate(R.layout.contacts_select_row, group, false); view.setTag(cursor.getPosition()); view.setOnClickListener(this); familyText = (TextView)view.findViewById(R.id.contacts_row_family_name); markedBox = (CheckBox)view.findViewById(R.id.contacts_row_check); familyText.setText(cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME))); boolean currentlyChecked = checkedState.get(cursor.getPosition()); markedBox.setChecked(currentlyChecked); setProgressBarIndeterminateVisibility(false); return super.getView(position, view, group); } public void onClick(View view) { int rowId = (Integer)view.getTag(); Log.d("OnClick", String.valueOf(rowId)); boolean currentlyChecked = checkedState.get(rowId); markedBox.setChecked(!currentlyChecked); checkedState.put(rowId, !currentlyChecked); Log.d("checkedState", "checkedState(" + rowId + ") = " + checkedState.get(rowId)); } } } 

Una llamada del método swapCursor de la clase SimpleCursorAdapter activará una función que correlaciona los nombres de columna de la matriz String proporcionada al constructor (el 4º parámetro) con una matriz de enteros que representan los índices de las columnas. Al pasar null en el constructor de MyAdapter para el array String representa los nombres de las columnas desde el cursor, esto lanzará una NullPointerException más tarde cuando el swapCursor intentará hacer la asignación (el NullPointerException debería aparecer en un método findColumns , que es el real Método que utiliza los nombres de columna String array).

La solución es pasar una matriz String válida, también puede hacer esto para la matriz int representa los ids para las vistas en las que colocar los datos:

 String[] from = {ContactsContract.Contacts.DISPLAY_NAME}; int[] to = {R.id.contacts_row_family_name, R.id.contacts_row_check}; adapter = new MyAdapter(this, R.layout.contacts_select_row, null, from, to, 0); 

No sé lo que está tratando de hacer, pero su implementación del método getView no es exactamente lo correcto:

Usted hace las cosas normales para el método getView (creación de diseños, búsqueda de vistas, datos de enlace) y luego simplemente devolver la vista de la superclase (?!?), Probablemente sólo verá el diseño por defecto con nada en ella.

La forma en que escribió el método getView no es muy eficiente, es posible que desee ver el reciclaje de la vista y el patrón del titular de la vista.

cursor.getPosition() no hará lo que quiera ya que no mueve el cursor a la posición correcta. De forma predeterminada, los adaptadores basados ​​en cursores lo harán para usted en el método getView , pero, al sobrepasar el método, es su tarea mover la posición del cursor.

Debe abandonar el método getView y utilizar los dos métodos newView y bindView ya que ofrecen una mejor separación de la lógica.

Adapter = new MyAdapter (esto, R.layout.contacts_select_row, null, null, null, 0);

Y su clase MyAdapter está pasando el cursor nulo

  public MyAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) { super(context, layout, c, from, to, flags); this.context = context; this.cursor = getCursor(); } 
  • Android - NullPointerException en SearchView en la barra de acciones
  • mapview.getoverlays () excepción de puntero nulo
  • ¿Cuál es la diferencia entre abrir una aplicación desde la pantalla de aplicaciones y la lista de aplicaciones utilizadas recientemente? (androide
  • NullPointerException acceder a las vistas en onCreate ()
  • ¿Qué es una NullPointerException y cómo puedo solucionarlo?
  • Buscador de Roman Nurik - cómo acceder a los datos recopilados?
  • No se puede iniciar la aplicación Android debido al error LogCollectManager.getUserType ()
  • Cómo serializar el valor nulo cuando se utiliza Parcelable interfaz
  • Inbuild de Android (ActionImageCapture) intento devuelve la intención nula. No puede entregar el resultado {who = null}
  • Intentar invocar método virtual 'android.os.Handler android.support.v4.app.FragmentHostCallback.getHandler ()' en una referencia de objeto nulo
  • ¿Qué está causando esta NullpointerException?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.