这个问题在这里已经有答案了:
java.lang.nullpointerexception:尝试对空对象引用[duplicate]调用接口方法'boolean android.database.cursor.movetofirst()'(1个答案)
什么是nullpointerexception,如何修复它(12个答案)
11天前关门了。
所有人!我在androidstudio4.1.1中有一个应用程序(refugio2),它有一个小数据库(只有一个表)。我已经添加了一个内容提供商。
这是应用程序树:
└── com
└── example
└── refugio2
├── data
│ ├── RefugioContract.java
│ ├── RefugioDbHelper.java
│ └── RefugioProvider.java
├── MainActivity.java
├── NuevoFragment.java
└── PrimerFragment.java
这是我的清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.refugio2">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Refugio2">
<provider
android:name="com.example.refugio2.data.RefugioProvider"
android:authorities="com.example.refugio2"
android:exported="true"/>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.Refugio2.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
这是合同类:
public final class RefugioContract {
//final para que no se pueda extender
//Para las uris del content provider
public static final String CONTENT_AUTHORITY="com.example.refugio2";
public static final Uri BASE_CONTENT_URI=Uri.parse("content://"+CONTENT_AUTHORITY);
public static final String PATH_MASCOTA="mascota";
//Private para que no pueda ser instanciada. La quiero sólo por sus constantes
private RefugioContract(){
}
//Una clase como esta por cada tabla de la Base de Datos
public static final class MascotaEntry implements BaseColumns{
//Uri para acceder al contenido de la tabla
public static final Uri CONTENT_URI=Uri.withAppendedPath(BASE_CONTENT_URI,PATH_MASCOTA);
//Tabla
public static final String TABLA="mascota";
//Columnas
public static final String COLUMNA_NOMBRE="nombre";
public static final String COLUMNA_ESPECIE="especie";
public static final String COLUMNA_SEXO="sexo";
public static final String COLUMNA_PESO="peso";
//Valores concretos para usar en algunas columnas
public static final int SEXO_MACHO=1;
public static final int SEXO_HEMBRA=2;
public static final int SEXO_DESCONOCIDO=0;
}
}
这是内容提供者类:
public class RefugioProvider extends ContentProvider {
//Para comprobar la validez de las uris que recibe
private static final int MASCOTA=1;
private static final int MASCOTA_ID=2;
private static final UriMatcher um=new UriMatcher(UriMatcher.NO_MATCH);
static{
um.addURI(RefugioContract.CONTENT_AUTHORITY, RefugioContract.PATH_MASCOTA,MASCOTA);
um.addURI(RefugioContract.CONTENT_AUTHORITY, RefugioContract.PATH_MASCOTA+"/#",MASCOTA_ID);
}
private RefugioDbHelper dbHelper;
public RefugioProvider() {
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public Uri insert(Uri uri, ContentValues values) {
//Aquí podríamos añadir chequeos con
// values.asString(MascotaEntry.COLUMNA_NOMBRE), o values.asFloat(MascotaEntry.COLUMNA.PESO) ...
//Y por ejemplo devolver una uri con id -100, -200... que indique el tipo de error
SQLiteDatabase db=dbHelper.getWritableDatabase();
long nuevoId;
switch(um.match(uri)){
case MASCOTA:
nuevoId=db.insert(RefugioContract.MascotaEntry.TABLA,null,values);
break;
default:
throw new IllegalArgumentException("Uri no válida: "+uri);
}
return ContentUris.withAppendedId(uri,nuevoId);
}
@Override
public boolean onCreate() {
dbHelper=RefugioDbHelper.getInstance(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteDatabase db=dbHelper.getReadableDatabase();
Cursor cursor=null;
switch(um.match(uri)){
case MASCOTA:
cursor=db.query(RefugioContract.MascotaEntry.TABLA,projection,
selection,selectionArgs,null,null,sortOrder);
break;
case MASCOTA_ID:
selection= RefugioContract.MascotaEntry._ID+"=?";
selectionArgs=new String[]{String.valueOf(ContentUris.parseId(uri))};
cursor=db.query(RefugioContract.MascotaEntry.TABLA,projection,
selection,selectionArgs,null,null,sortOrder);
break;
default:
throw new IllegalArgumentException("Uri no válida: "+uri);
}
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO: Implement this to handle requests to update one or more rows.
throw new UnsupportedOperationException("Not yet implemented");
}
}
在应用程序中一切正常。但是。。。我制作了另一个应用程序(refugioconsumidor)作为此内容提供商的客户端,只需一个主要活动:
package com.example.refugioconsumidor;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.RemoteException;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView contenido;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
ContentResolver cr =getApplicationContext().getContentResolver();
Cursor cursor= null;
cursor = cr.query(Uri.parse("content://com.example.refugio2/mascota"),
null,null,null,null);
while(cursor.moveToNext()){
int id=cursor.getInt(1);
String nombre=cursor.getString(2);
String especie=cursor.getString(3);
int sexo=cursor.getInt(4);
float peso=cursor.getFloat(5);
contenido.append(id+" - "+nombre+" - "+especie+" - "+sexo+" - "+peso+"\n");
}
cursor.close();
}
}
当我在emulator上运行它时,它找不到内容提供程序,并且由于游标为null而引发以下错误:
12/29 08:51:10: Launching 'app' on Nexus 5X API 30.
Install successfully finished in 225 ms.
$ adb shell am start -n "com.example.refugioconsumidor/com.example.refugioconsumidor.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Connected to process 2983 on device 'emulator-5554'.
Capturing and displaying logcat messages from application. This behavior can be disabled in the "Logcat output" section of the "Debugger" settings page.
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
D/NetworkSecurityConfig: No Network Security Config specified, using platform default
D/libEGL: loaded /vendor/lib/egl/libEGL_emulation.so
D/libEGL: loaded /vendor/lib/egl/libGLESv1_CM_emulation.so
D/libEGL: loaded /vendor/lib/egl/libGLESv2_emulation.so
W/fugioconsumido: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed)
W/fugioconsumido: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed)
E/ActivityThread: Failed to find provider info for com.example.refugio2
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.refugioconsumidor, PID: 2983
java.lang.NullPointerException: Attempt to invoke interface method 'boolean android.database.Cursor.moveToNext()' on a null object reference
at com.example.refugioconsumidor.MainActivity.onStart(MainActivity.java:30)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1435)
at android.app.Activity.performStart(Activity.java:8024)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3475)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
我认为问题与内容提供商身份有关。¿有人能帮忙吗?
暂无答案!
目前还没有任何答案,快来回答吧!