加载程序错误:java.lang.NullPointerException:尝试调用接口方法 'boolean android.database.Cursor.moveToFirst()'
Error in Loader: java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()'
我想使用 Loader 时遇到问题,我想从另一个应用程序检索信息,这些信息是用 Content Provider 保存的,并检查数据是否正确保存,数据库创建没有问题, 但是当使用 Loader 的方法时给我这个错误:
java.lang.NullPointerException: Attempt to invoke interface method
'boolean android.database.Cursor.moveToFirst()' on a null object
reference
我不知道为什么会出现这个错误,我的 class 已经检查过它并且包的名称和表的名称是正确的,这是我的 class 我实施的地方我的装载机:
public class principal extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>{
TextView textView = null;
CursorLoader cursorLoader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_principal);
textView = (TextView) findViewById(R.id.texto);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitle("Control de Tareas");
toolbar.setSubtitle("Mis tareas");
listar();
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
cursorLoader = new CursorLoader(this, Uri.parse("content://com.example.enriq.examen_tareas_segundo_plano_enrique_espinosa.ProviderContenedor/cte"), null, null, null, null);
return cursorLoader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
try {
data.moveToFirst();
StringBuilder txt = new StringBuilder();
while (!data.isAfterLast()){
txt.append("\n"+data.getString(data.getColumnIndex("id"))+" - " +data.getString(data.getColumnIndex("nombre_tarea"))+" - " +data.getString(data.getColumnIndex("nota")));
data.moveToNext();
}
textView.setText(txt);
}catch (Exception e){
Toast.makeText(principal.this, "No se pudo recuperar datos: ", Toast.LENGTH_LONG).show();
Log.i("Error","Este es el error: "+e);
}
}
public void listar(){
Toast.makeText(principal.this, "Desplegando", Toast.LENGTH_SHORT).show();
getSupportLoaderManager().initLoader(1,null,this);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
@Override
public void onDestroy(){
super.onDestroy();
}
}
我明白没有必要在我的清单中添加任何额外的权限
现在,这是我的 class,我在其中实现我的内容提供程序,这个 class 在不同的项目中,我在这里声明我所有的变量和方法:
public class ProviderContenedor extends ContentProvider {
private SQLiteDatabase db;
static final String DATABASE_NAME = "tareas";
static final String TABLE_NAME = "datos";
static final int DATABASE_VERSION = 1;
static final String Sentencia = "CREATE TABLE "+ TABLE_NAME
+ "(id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "nombre_tarea TEXT NOT NULL,"
+ "nota TEXT NOT NULL);";
static final String id = "id";
static final String name = "nombre_tarea";
static final String nota = "nota";
static final int uriCode = 1;
static final UriMatcher uriMatcher;
static final String NOMBREPROVIDER = "com.example.enriq.examen_tareas_segundo_plano_enrique_espinosa.ProviderContenedor";
static final String URL = "content://" + NOMBREPROVIDER + "/cte";
static final Uri CONTENEDORURI = Uri.parse(URL);
private static HashMap<String, String> values;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(NOMBREPROVIDER, "cte", uriCode);
uriMatcher.addURI(NOMBREPROVIDER, "cte/*", uriCode);
}
@Override
public boolean onCreate() {
Context context = getContext();
DatabaseHelper dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
if (db != null) {
return true;
}
return false;
}
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context){
super(context, DATABASE_NAME, null,DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(Sentencia);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s, @Nullable String[] strings1, @Nullable String s1) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
long roWID = db.insert(TABLE_NAME, "", values);
if(roWID > 0){
Uri _uri = ContentUris.withAppendedId(CONTENEDORURI, roWID);
getContext().getContentResolver().notifyChange(_uri, null);
//Toast.makeText(getContext(),"Se a guardado la nueva tarea en el proveedor de contenidos",Toast.LENGTH_LONG).show();
return _uri;
}
throw new SQLException("Error al agregar una nueva tarea en "+uri);
}
@Override
public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
return 0;
}
}
query
方法在 ContentProvider 中被覆盖,它始终 returns null。因此,您从该提供商获得的任何游标都是空的。
我想使用 Loader 时遇到问题,我想从另一个应用程序检索信息,这些信息是用 Content Provider 保存的,并检查数据是否正确保存,数据库创建没有问题, 但是当使用 Loader 的方法时给我这个错误:
java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.database.Cursor.moveToFirst()' on a null object reference
我不知道为什么会出现这个错误,我的 class 已经检查过它并且包的名称和表的名称是正确的,这是我的 class 我实施的地方我的装载机:
public class principal extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>{
TextView textView = null;
CursorLoader cursorLoader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_principal);
textView = (TextView) findViewById(R.id.texto);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitle("Control de Tareas");
toolbar.setSubtitle("Mis tareas");
listar();
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
cursorLoader = new CursorLoader(this, Uri.parse("content://com.example.enriq.examen_tareas_segundo_plano_enrique_espinosa.ProviderContenedor/cte"), null, null, null, null);
return cursorLoader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
try {
data.moveToFirst();
StringBuilder txt = new StringBuilder();
while (!data.isAfterLast()){
txt.append("\n"+data.getString(data.getColumnIndex("id"))+" - " +data.getString(data.getColumnIndex("nombre_tarea"))+" - " +data.getString(data.getColumnIndex("nota")));
data.moveToNext();
}
textView.setText(txt);
}catch (Exception e){
Toast.makeText(principal.this, "No se pudo recuperar datos: ", Toast.LENGTH_LONG).show();
Log.i("Error","Este es el error: "+e);
}
}
public void listar(){
Toast.makeText(principal.this, "Desplegando", Toast.LENGTH_SHORT).show();
getSupportLoaderManager().initLoader(1,null,this);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
@Override
public void onDestroy(){
super.onDestroy();
}
}
我明白没有必要在我的清单中添加任何额外的权限 现在,这是我的 class,我在其中实现我的内容提供程序,这个 class 在不同的项目中,我在这里声明我所有的变量和方法:
public class ProviderContenedor extends ContentProvider {
private SQLiteDatabase db;
static final String DATABASE_NAME = "tareas";
static final String TABLE_NAME = "datos";
static final int DATABASE_VERSION = 1;
static final String Sentencia = "CREATE TABLE "+ TABLE_NAME
+ "(id INTEGER PRIMARY KEY AUTOINCREMENT,"
+ "nombre_tarea TEXT NOT NULL,"
+ "nota TEXT NOT NULL);";
static final String id = "id";
static final String name = "nombre_tarea";
static final String nota = "nota";
static final int uriCode = 1;
static final UriMatcher uriMatcher;
static final String NOMBREPROVIDER = "com.example.enriq.examen_tareas_segundo_plano_enrique_espinosa.ProviderContenedor";
static final String URL = "content://" + NOMBREPROVIDER + "/cte";
static final Uri CONTENEDORURI = Uri.parse(URL);
private static HashMap<String, String> values;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(NOMBREPROVIDER, "cte", uriCode);
uriMatcher.addURI(NOMBREPROVIDER, "cte/*", uriCode);
}
@Override
public boolean onCreate() {
Context context = getContext();
DatabaseHelper dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
if (db != null) {
return true;
}
return false;
}
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context){
super(context, DATABASE_NAME, null,DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(Sentencia);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s, @Nullable String[] strings1, @Nullable String s1) {
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
long roWID = db.insert(TABLE_NAME, "", values);
if(roWID > 0){
Uri _uri = ContentUris.withAppendedId(CONTENEDORURI, roWID);
getContext().getContentResolver().notifyChange(_uri, null);
//Toast.makeText(getContext(),"Se a guardado la nueva tarea en el proveedor de contenidos",Toast.LENGTH_LONG).show();
return _uri;
}
throw new SQLException("Error al agregar una nueva tarea en "+uri);
}
@Override
public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
return 0;
}
}
query
方法在 ContentProvider 中被覆盖,它始终 returns null。因此,您从该提供商获得的任何游标都是空的。