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).
- Excepción de puntero nulo al utilizar SearchView con AppCompat
- Actualización de Eclipse no funciona
- Fije onclicklistener en un botón dentro de un DialogFragment
- No se puede reanudar la actividad
- Excepción de puntero NULL de getSupportFragmentManager de Android en Fragmento
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)); } } }
- setText () no funciona en el diseño hinchado
- Android get La barra de acción de soporte siempre devuelve NULL
- NullPointerException intentando acceder a un recurso de cadena
- App fallando debido a la excepción nullpointer
- Nullpointer excepción en oncreateView () de fragmento
- NullPointerException en FirebaseMessagingService.zzo (fuente desconocida)
- Java.lang.NullPointerException: Intenta invocar el método virtual 'ActionBar.setNavigationMode (int)' en una referencia de objeto nulo
- NullPointerException: Intento de leer del campo 'int android.view.View.mViewFlags'
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 Live Wallpaper prácticas de rendimiento y ahorro de la batería?
- ¿Es posible detectar dispositivos Android que se encuentran lado a lado