開發自定義 ContentProvider 時,代碼邏輯看似正確,但運行崩潰。經排查,核心問題在於 ContentProvider 未在 AndroidManifest.xml 中正確註冊,且數據庫建表 SQL 語句存在語法錯誤。
// 錯誤寫法:缺少空格導致 SQL 語法錯誤
public static final String CREATETABLE = "create table" + TABLENAME + "(_id integer primary key,username text,userpassword text);";
// 實際生成:"create tableuserinfo(_id integer primary key,username text,userpassword text);"
public static final String CREATETABLE = "create table " + TABLENAME + " (_id integer primary key, username text, userpassword text);";
<!-- AndroidManifest.xml 中配置 -->
<provider
android:name="com.chapt6.UserProvider"
android:authorities="com.chapt6.userprovider"
android:exported="false">
</provider>
<!-- 代碼中實際使用的 AUTHORITY -->
private static final String AUTHORITY = "com.chapt6.userprovider";
public static final Uri CONTENT_URI = Uri.parse("content://com.chapt6.userprovider/userinfo");
注意:包名為 com.example.definecontentprovider,但 Provider 聲明在 com.chapt6.UserProvider,需確保類路徑正確。
public boolean onCreate() {
dbh = new DataBaseHelpe(getContext());
return false; // 應返回 true 表示初始化成功
}
public class DataBaseHelpe extends SQLiteOpenHelper {
public static final String DB_NAME = "userdb.db";
public static final String TABLENAME = "userinfo";
public static final int DB_VERSION = 1;
// 修正:添加空格,規範 SQL 格式
public static final String CREATETABLE = "CREATE TABLE " + TABLENAME + " (_id INTEGER PRIMARY KEY, username TEXT, userpassword TEXT);";
public DataBaseHelpe(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATETABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLENAME);
onCreate(db);
}
}
public class UserProvider extends ContentProvider {
// ... 其他代碼 ...
@Override
public boolean onCreate() {
dbh = new DataBaseHelpe(getContext());
return true; // 修正:返回 true
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = dbh.getWritableDatabase();
long id = db.insert("userinfo", null, values);
if (id > -1) {
Uri insertUri = ContentUris.withAppendedId(CONTENT_URI, id);
getContext().getContentResolver().notifyChange(insertUri, null);
return insertUri;
}
return null;
}
// ... 其他 CRUD 方法 ...
}
adb logcat 查看詳細崩潰堆棧AndroidManifest.xml 中 provider 的 android:name 是否為完整類名authorities 屬性與代碼中 AUTHORITY 常量完全一致onCreate() 中添加日誌確認初始化流程ContentProvider 開發的三大核心要點:SQL 語法規範、Manifest 註冊準確、生命周期返回值正確。細節決定成敗,建立標準化檢查清單能有效避免此類低級錯誤。