目前我正在使用db.query()
方法直接访问数据库,代码运行完美。但是,当我尝试使用内容解析器使用Cursor cursor = getContentResolver().query()
方法访问数据库时,该应用程序无法启动。我创建了Contract类来存储常量和CustomerProvider类以用作ContentProvider
。
CatalogActivity(mainActivity):
public class CatalogActivity extends AppCompatActivity {
private CustomerDbHelper mdbHelper;
Button addbutton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_catalog);
addbutton= (Button) findViewById(R.id.addButton);
addbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(CatalogActivity.this, AddCustomerActivity.class);
startActivity(intent);
}
});
mdbHelper=new CustomerDbHelper(this);
displayDatabaseInfo();
}
@Override
protected void onStart() {
super.onStart();
displayDatabaseInfo();
}
protected void displayDatabaseInfo(){
CustomerDbHelper mdbHelper=new CustomerDbHelper(this);
SQLiteDatabase db=mdbHelper.getReadableDatabase();
String[] projection={CustomerEntry._ID,
CustomerEntry.COLUMN_CUSTOMER_NAME,
CustomerEntry.COLUMN_CUSTOMER_ADDRESS,
CustomerEntry.COLUMN_CUSTOMER_PHONE };
// Cursor cursor = db.query(CustomerEntry.TABLE_NAME,projection,null,null,null,null,null);//when i use this command code runs perfectly
Cursor cursor = getContentResolver().query(
CustomerEntry.CONTENT_URI,
projection,
null,
null,
null); // i want to use this method but here problem occur,App doesn't stars.
try {
TextView TV1 = (TextView) findViewById(R.id.tv1);
TV1.setText("NUMBER OF ROWS= " + cursor.getCount());
TV1.append("\n"+"currentId-currentname-currentaddress-cureentphone");
int idColumnIndex=cursor.getColumnIndex(CustomerEntry._ID);
int nameColumnIndex = cursor.getColumnIndex(CustomerEntry.COLUMN_CUSTOMER_NAME);
int addressColumnIndex = cursor.getColumnIndex(CustomerEntry.COLUMN_CUSTOMER_ADDRESS);
int phoneColumnIndex = cursor.getColumnIndex(CustomerEntry.COLUMN_CUSTOMER_PHONE);
while(cursor.moveToNext()){
int currentId=cursor.getInt(idColumnIndex);
String currentname = cursor.getString(nameColumnIndex);
String currentaddress = cursor.getString(addressColumnIndex);
int currentphone = cursor.getInt(phoneColumnIndex);
TV1.append("\n"+currentId+"-"+currentname+"-"+currentaddress+"-"+currentphone);
}
}
finally {
cursor.close();
}
}
CutomerContract(合约类):
public final class CustomerContract {
private CustomerContract() {
}
public static final String CONTENT_AUTHORITY = "com.example.android.try1";
public static final Uri BASE_CONTENT_AUTHORITY = Uri.parse("content://" + CONTENT_AUTHORITY);
public static final String PATH_CUSTOMER_TABLE = "customer";
public static final class CustomerEntry implements BaseColumns {
public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_AUTHORITY, PATH_CUSTOMER_TABLE);
public final static String TABLE_NAME = "customer";
public final static String _ID = BaseColumns._ID;
public final static String COLUMN_CUSTOMER_NAME = "name";
public final static String COLUMN_CUSTOMER_ADDRESS = "address";
public final static String COLUMN_CUSTOMER_PHONE = "phone";
}
}
CustomerProvider(Contentprovider)类
public class CustomerProvider extends ContentProvider {
private CustomerDbHelper mDbHelper;
private static final int CUSTOMER = 100;
private static final int CUSTOMER_ID =101;
private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
sUriMatcher.addURI(CustomerContract.CONTENT_AUTHORITY,CustomerContract.PATH_CUSTOMER_TABLE,CUSTOMER);
sUriMatcher.addURI(CustomerContract.CONTENT_AUTHORITY,CustomerContract.PATH_CUSTOMER_TABLE + "/#",CUSTOMER_ID);
}
@Override
public boolean onCreate() {
mDbHelper=new CustomerDbHelper(getContext());
return true;
}
@Nullable
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
SQLiteDatabase database = mDbHelper.getReadableDatabase();
Cursor cursor;
int match = sUriMatcher.match(uri);
switch (match){
case CUSTOMER:
cursor = database.query(CustomerEntry.TABLE_NAME, projection, selection, selectionArgs,
null, null, sortOrder);
break;
case CUSTOMER_ID:
selection = CustomerEntry._ID + "=?";
selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
cursor = database.query(CustomerEntry.TABLE_NAME, projection,selection,selectionArgs,null,null,sortOrder);
break;
default:
throw new IllegalArgumentException("Cannot query unknown URI " + uri);
}
return cursor;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
return 0;
}
}
Logcat显示以下消息:
09-15 02:55:02.768 3391-3391/com.example.android.try1 E/ActivityThread: Failed to find provider info for com.example.android.try1
09-15 02:55:02.768 3391-3391/com.example.android.try1 D/AndroidRuntime: Shutting down VM
09-15 02:55:02.769 3391-3391/com.example.android.try1 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.try1, PID: 3391
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.try1/com.example.android.try1.CatalogActivity}: java.lang.NullPointerException: Attempt to invoke interface method 'void android.database.Cursor.close()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'void android.database.Cursor.close()' on a null object reference
at com.example.android.try1.CatalogActivity.displayDatabaseInfo(CatalogActivity.java:91)
at com.example.android.try1.CatalogActivity.onCreate(CatalogActivity.java:40)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)