Java DBHelper.GetWirtableDatabase引发空异常
我正在尝试为用户编写自己的内容提供商代码。当我尝试验证用户是否存在时,当DBHelper尝试创建数据库时,它抛出一个null异常 以下是内容提供商:Java DBHelper.GetWirtableDatabase引发空异常,java,android,sqlite,nullpointerexception,android-contentprovider,Java,Android,Sqlite,Nullpointerexception,Android Contentprovider,我正在尝试为用户编写自己的内容提供商代码。当我尝试验证用户是否存在时,当DBHelper尝试创建数据库时,它抛出一个null异常 以下是内容提供商: public class MyUserProvider extends ContentProvider { private UserDBHelper db; private static final int USERS = 10; private static final int USER_ID = 20; pr
public class MyUserProvider extends ContentProvider {
private UserDBHelper db;
private static final int USERS = 10;
private static final int USER_ID = 20;
private static final String AUTHORITY =
"net.ifo420.ritc.agenda.userprovider";
private static final String BASE_PATH = "users";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/" + BASE_PATH);
public static final String CONTENT_TYPE =
ContentResolver.CURSOR_DIR_BASE_TYPE + "/users";
public static final String CONTENT_ITEM_TYPE =
ContentResolver.CURSOR_ITEM_BASE_TYPE + "/user";
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
uriMatcher.addURI(AUTHORITY, BASE_PATH, USERS);
uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", USER_ID);
}
public MyUserProvider() {
}
@Override
public boolean onCreate() {
db = new UserDBHelper(getContext());
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
checkColumns(projection);
queryBuilder.setTables(UserTable.TABLE);
int uriType = uriMatcher.match(uri);
switch (uriType) {
case USERS:
break;
case USER_ID:
queryBuilder.appendWhere(UserTable.COLUMN_ID + " = " + uri.getLastPathSegment());
break;
default:
throw new IllegalArgumentException("Uknown uri " + uri);
}
SQLiteDatabase db1 = db.getReadableDatabase();
Cursor cursor = queryBuilder.query(db1, projection, selection, selectionArgs,
null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int uriType = uriMatcher.match(uri);
SQLiteDatabase database = db.getReadableDatabase();
long id = 0;
switch (uriType) {
case USERS:
id = database.insert(UserTable.TABLE, null, values);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_PATH + "/" + id);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int uriType = uriMatcher.match(uri);
SQLiteDatabase sqLiteDatabase = db.getReadableDatabase();
int rowsDeleted = 0;
switch (uriType) {
case USERS:
rowsDeleted = sqLiteDatabase.delete(UserTable.TABLE, selection,
selectionArgs);
break;
case USER_ID:
String id = uri.getLastPathSegment();
if(TextUtils.isEmpty(selection)) {
rowsDeleted = sqLiteDatabase.delete(UserTable.TABLE,
UserTable.COLUMN_ID + " = " + id, null);
} else {
rowsDeleted = sqLiteDatabase.delete(UserTable.TABLE,
UserTable.COLUMN_ID + " = " + id + " and " +
selection, selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int uriType = uriMatcher.match(uri);
SQLiteDatabase sqLiteDatabase = db.getReadableDatabase();
int rowsUpdated = 0;
switch (uriType) {
case USERS:
rowsUpdated = sqLiteDatabase.update(UserTable.TABLE,
values,
selection,
selectionArgs);
break;
case USER_ID:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsUpdated = sqLiteDatabase.update(UserTable.TABLE,
values,
UserTable.COLUMN_ID + "=" + id,
null);
} else {
rowsUpdated = sqLiteDatabase.update(UserTable.TABLE,
values,
UserTable.COLUMN_ID + "=" + id
+ " and "
+ selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
private void checkColumns(String[] projection) {
String[] available = {UserTable.COLUMN_USERNAME, UserTable.COLUMN_PASSWORD,
UserTable.COLUMN_ID};
if (projection != null) {
HashSet<String> requestedColumns =
new HashSet<String>(Arrays.asList(projection));
HashSet<String> availableColumns =
new HashSet<String>(Arrays.asList(available));
if (!availableColumns.containsAll(requestedColumns)) {
throw new IllegalArgumentException("Unknown columns in projection");
}
}
}
以下是logcat给我的信息:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase net.info420.ritc.agendacegep.UserDBHelper.getReadableDatabase()' on a null object reference
at net.info420.ritc.agendacegep.MyUserProvider.query(MyUserProvider.java:70)
at net.info420.ritc.agendacegep.LoginActivity.utilisateurExiste(LoginActivity.java:69)
at net.info420.ritc.agendacegep.LoginActivity.onClick(LoginActivity.java:57)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22260)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
您不能直接实例化和调用ContentProvider—您必须通过内容解析器。否则它不会经过提供者的生命周期,也不会调用onCreate。好吧,我有自己的答案。是的,我不能实例化我的ContentProvider,但不仅仅如此。我更改了代码,意识到我只是没有真正理解查询中的selection和SelectionAgs参数 所以它是从:
private boolean userExists() {
String username = nomUtilisateur.getText().toString();
String password = motPasse.getText().toString();
Cursor users = userProvider.query(MyUserProvider.CONTENT_URI,
null,
" WHERE username = " + nomUtilisateur.getText().toString() +
" AND password = " + motPasse.getText().toString(), null, null);
if (users.getCount() != 0) {
return true;
} else {
return false;
}
}
致:
因此,游标为空是因为我没有进行正确的查询,这就是为什么没有创建数据库的原因:因为我在代码的末尾不需要它。在
onCreate
中尝试返回true
,它仍然不起作用。现在,当我尝试获取游标返回的结果数时,它会抛出异常。它说它是空的,当我试图查看数据库时,它没有被创建。好的,我已经用标记运行了一些测试,我注意到onCreate方法是在我的应用程序开始时调用的,而不是在我想使用getWritableDatabase()时。而且query()方法即使在我调用它的时候也不会被调用,所以游标为null是正常的,但是数据库仍然没有被创建。我得到了答案,部分问题就是你提到的。谢谢
private boolean userExists() {
String username = nomUtilisateur.getText().toString();
String password = motPasse.getText().toString();
Cursor users = userProvider.query(MyUserProvider.CONTENT_URI,
null,
" WHERE username = " + nomUtilisateur.getText().toString() +
" AND password = " + motPasse.getText().toString(), null, null);
if (users.getCount() != 0) {
return true;
} else {
return false;
}
}
private boolean userExists() {
String username = nomUtilisateur.getText().toString();
String password = motPasse.getText().toString();
String[] selection = {username, password};
Cursor users = getApplicationContext().getContentResolver().query
(Agenda.UserEntry.CONTENT_URI,
null,
"username = ? AND password = ?", selection, null);
if (users.getCount() != 0) {
return true;
} else {
return false;
}
}