【问题标题】:ContentProvider fails on insertContentProvider 在插入时失败
【发布时间】:2010-07-30 14:25:53
【问题描述】:

我是 android 开发的新手,遇到了一些我似乎无法绕过的绊脚石。

使用记事本示例,我创建了自己的 ContentProvider 来提供来自我最终将托管在网络服务器上的数据库中的数据。但这距离我现在的位置还有光年。

只是测试我的 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);
    }

}

堆栈跟踪


07-30 10:22:19.078:错误/AndroidRuntime(10903):未捕获的处理程序:线程主因未捕获的异常而退出 07-30 10:22:19.208: 错误/AndroidRuntime(10903): java.lang.RuntimeException: 无法启动活动 ComponentInfo{com.vortex.rules/com.vortex.rules.MainWindow}: java.lang.NullPointerException 07-30 10:22:19.208: 错误/AndroidRuntime(10903): 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2444) 07-30 10:22:19.208: 错误/AndroidRuntime(10903): 在 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.208: 错误/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: 错误/AndroidRuntime(10903): 在 android.os.Looper.loop(Looper.java:123) 07-30 10:22:19.208: 错误/AndroidRuntime(10903): 在 android.app.ActivityThread.main(ActivityThread.java:4246) 07-30 10:22:19.208: 错误/AndroidRuntime(10903): 在 java.lang.reflect.Method.invokeNative(Native Method) 07-30 10:22:19.208: 错误/AndroidRuntime(10903): 在 java.lang.reflect.Method.invoke(Method.java:521) 07-30 10:22:19.208: 错误/AndroidRuntime(10903): 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791) 07-30 10:22:19.208: 错误/AndroidRuntime(10903): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549) 07-30 10:22:19.208:错误/AndroidRuntime(10903):在 dalvik.system.NativeStart.main(本机方法) 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: 错误/AndroidRuntime(10903): 在 com.vortex.rules.CoreRulesProvider.insert(CoreRulesProvider.java:157) 07-30 10:22:19.208: 错误/AndroidRuntime(10903): 在 com.vortex.rules.MainWindow.onCreate(MainWindow.java:42) 07-30 10:22:19.208: 错误/AndroidRuntime(10903): 在 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: 错误/AndroidRuntime(10903): ... 11 更多

【问题讨论】:

    标签: android


    【解决方案1】:

    最终我自己解决了这个问题。原来我的 URI 中缺少一个字母,已修复。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-23
      • 2012-08-13
      相关资源
      最近更新 更多