我是一個全新的android開發人員,並且遇到了一些我無法解決的絆腳石。ContentProvider插入失敗
使用NotePad示例,我創建了自己的ContentProvider來提供最終將託管在Web服務器上的數據庫中的數據。但距離我現在所在的地方還有光年。
只是測試我的ContentProvider引起了一些我無法解決的頭痛。出於某種原因,當提供者調用SQLiteDatabase db = mOpenHelper.getWritableDatabase();
時,我得到一個空指針異常。
代碼如下:
MainWindow.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/**
* Check for DB, if none, d/l from web server
*/
Uri first_use = Rules.CONTENT_URI;
ContentResolver cr = getContentResolver();
Cursor c = cr.query(first_use, null, null, null, null);
if(c == null){
ContentProvider cp = new CoreRulesProvider();
if (cp.onCreate()) {
ContentValues values = new ContentValues();
values.put(Rules._ID, 1);
values.put(Rules.TERM, "Player");
values.put(Rules.TEXT, "You, the person reading these rules, are a Player.");
cp.insert(Rules.CONTENT_URI, values);
}
}
RulesContentProvider.java
package com.vortex.rules;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import java.util.HashMap;
import com.vortex.rules.Rule.Rules;
/**
* Provides access to a database of rules. Each rule has a TERM, the RULE itself, and a creation date and modified data.
* @author Michael Martin
*
*/
public class CoreRulesProvider extends ContentProvider {
private static final String TAG = "CoreRulesProvider";
private static final String DATABASE_NAME = "core_rules.db";
private static final int DATABASE_VERSION = 2;
private static final String RULES_TABLE_NAME = "rules";
private static HashMap<String, String> sRulesProjectionMap;
private static HashMap<String, String> sLiveFolderProjectionMap;
private static final int RULES = 1;
private static final int RULE_ID = 2;
private static final int LIVE_FOLDER_RULES = 3;
private static final UriMatcher sUriMatcher;
/**
* This class helps open, create, and upgrade the database file.
*/
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + RULES_TABLE_NAME + " ("
+ Rules._ID + " INTEGER PRIMARY KEY,"
+ Rules.TERM + " TEXT,"
+ Rules.TEXT + " LONGTEXT"
+ ");");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS rules");
onCreate(db);
}
}
/**
* END OF DatabaseHelper CLASS!!!!!
*/
private DatabaseHelper mOpenHelper;
@Override
public boolean onCreate() {
mOpenHelper = new DatabaseHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(RULES_TABLE_NAME);
switch (sUriMatcher.match(uri)) {
case RULES:
qb.setProjectionMap(sRulesProjectionMap);
break;
case RULE_ID:
qb.setProjectionMap(sLiveFolderProjectionMap);
qb.appendWhere(Rules._ID + "=" + uri.getPathSegments().get(1));
break;
default:
throw new IllegalArgumentException("Uknown URI " + uri);
}
//If no sort order is specified, use the default
String orderBy;
if (TextUtils.isEmpty(sortOrder)) {orderBy = Rules.DEFAULT_SORT_ORDER;
} else {
orderBy = sortOrder;
}
//Get the database and run the query
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
//Tell the cursor what uri to watch, so it knows when its source data changes
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
@Override
public String getType(Uri uri) {
switch (sUriMatcher.match(uri)) {
case RULES:
case LIVE_FOLDER_RULES:
return Rules.CONTENT_TYPE;
case RULE_ID:
return Rules.CONTENT_ITEM_TYPE;
default:
throw new IllegalArgumentException("Uknown URI " + uri);
}
}
public Uri insert(Uri uri, ContentValues initialValues) {
//Validate the requested uri
if (sUriMatcher.match(uri) != RULES) {
throw new IllegalArgumentException("Uknown URI " + uri);
}
ContentValues values;
if (initialValues != null) {
values = new ContentValues(initialValues);
} else {
values = new ContentValues();
}
//Make sure that the fields are all set
if (values.containsKey(Rules.TERM) == false) {
Resources r = Resources.getSystem();
values.put(Rules.TERM, r.getString(android.R.string.untitled));
}
if (values.containsKey(Rules.TEXT) == false) {
values.put(Rules.TEXT, "");
}
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
long rowId = db.insert(RULES_TABLE_NAME, Rules.TEXT, values);
if (rowId > 0) {
Uri ruleUri = ContentUris.withAppendedId(Rules.CONTENT_URI, rowId);
getContext().getContentResolver().notifyChange(ruleUri, null);
return ruleUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
public int delete(Uri uri, String where, String[] whereArgs) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
switch (sUriMatcher.match(uri)) {
case RULES:
count = db.delete(RULES_TABLE_NAME, where, whereArgs);
break;
case RULE_ID:
String ruleId = uri.getPathSegments().get(1);
count = db.delete(RULES_TABLE_NAME, Rules._ID + "=" + ruleId
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""),
whereArgs);
break;
default:
throw new IllegalArgumentException("Uknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
switch (sUriMatcher.match(uri)) {
case RULES:
count = db.update(RULES_TABLE_NAME, values, where, whereArgs);
break;
case RULE_ID:
String ruleId = uri.getPathSegments().get(1);
count = db.update(RULES_TABLE_NAME, values, Rules._ID + "=" + ruleId
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : "")
, whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(Rule.AUTHORITY, "rules", RULES);
sUriMatcher.addURI(Rule.AUTHORITY, "rules/#", RULE_ID);
sUriMatcher.addURI(Rule.AUTHORITY, "live_folders/rules", LIVE_FOLDER_RULES);
sRulesProjectionMap = new HashMap<String, String>();
sRulesProjectionMap.put(Rules._ID, Rules._ID);
sRulesProjectionMap.put(Rules.TERM, Rules.TERM);
sRulesProjectionMap.put(Rules.TEXT, Rules.TEXT);
}
}
堆棧跟蹤
10月7日至30日:22:19.078:ERROR/AndroidRuntime(10903):未捕獲的處理程序:線程退出主要由於未捕獲的異常 10月7日至30日:22:19.208:ERROR/AndroidRuntime(10903):JAVA。 lang.RuntimeException:無法啓動活動ComponentInfo {com.vortex.rules/com.vortex.rules.MainWindow}:java.lang.NullPointerException 07-30 10:22:19.208:ERROR/AndroidRuntime(10903):at android。 app.ActivityThread.performLaunchActivity(ActivityThread.java:2444) 07-30 10:22:19.208:ERROR/AndroidRuntime(10903):at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2460) 07-30 10: 22:19.208:錯誤/ AndroidRuntime(10903):在android.app.ActivityThread.access $ 2300(ActivityThread.java:119) 07-30 10:22:19.20 8:錯誤/ AndroidRuntime(10903):在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1837) 07-30 10:22:19.208:錯誤/ AndroidRuntime(10903):在android.os.Handler。 dispatchMessage(Handler.java:99) 07-30 10:22:19.208:ERROR/AndroidRuntime(10903):at android.os.Looper.loop(Looper.java:123) 07-30 10:22:19.208: ERROR/AndroidRuntime(10903):at android.app.ActivityThread.main(ActivityThread.java:4246) 07-30 10:22:19.208:ERROR/AndroidRuntime(10903):at java.lang.reflect.Method.invokeNative Native Method) 07:10:22:19.208:ERROR/AndroidRuntime(10903):at java.lang.reflect.Method.invoke(Method.java:521) 07-30 10:22:19.208:ERROR/AndroidRuntime (10903):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:791) 07-30 10:22:19.208:E RROR/AndroidRuntime(10903):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549) 07-30 10:22:19.208:ERROR/AndroidRuntime(10903):at dalvik.system.NativeStart。主(本機方法) 07-30 10:22:19.208:錯誤/ AndroidRuntime(10903):導致:java.lang.NullPointerException 07-30 10:22:19.208:錯誤/ AndroidRuntime(10903):在android。 database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98) 07-30 10:22:19.208:ERROR/AndroidRuntime(10903):at com.vortex.rules.CoreRulesProvider.insert(CoreRulesProvider.java:157) 07 -30 10:22:19.208:ERROR/AndroidRuntime(10903):at com.vortex.rules.MainWindow.onCreate(MainWindow.java:42) 07-30 10:22:19.208:ERROR/AndroidRuntime(10903):at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123) 07-30 10:22:19.208:錯誤/ AndroidRuntime(10903):在android.app.ActivityThread.performLaunchActivity(ActivityThread。java:2407) 07-30 10:22:19.208:ERROR/AndroidRuntime(10903):... 11更多