我正在尝试使用我创建的ContentProvider在我的活动中填充ListView,但是当调用onLoadFinished()方法时,它会收到一个null Cursor。 (尽管CursorLoader不为null)
我正在尝试调试ContentProvider,但调试器不会停止在query()方法上(它在URI不匹配时停止,当我修复它时,它不会停止!!!)。因此,如果没有调试,我很难找到为什么我的光标在onLoadFinished()方法上返回为null。
以下是活动的代码:
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.view.Menu;
import android.widget.ListView;
public class PicturesListActivity extends FragmentActivity
implements LoaderManager.LoaderCallbacks<Cursor> {
SimpleCursorAdapter myAdapter;
String[] projection = {"_id", "name"};
String[] from = {"name"};
String orderBy = "year DESC";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pictures_list);
final ListView listview = (ListView) findViewById(R.id.lv_pictures_list);
// The TextView in simple_list_item_1
int[] toViews = {android.R.id.text1};
// Prepare the loader. Either re-connect with an existing one, or start a new one.
getSupportLoaderManager().initLoader(0, null, this);
myAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, null, from, toViews, 0);
listview.setAdapter(myAdapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.pictures_list, menu);
return true;
}
@Override
// Called when a new Loader needs to be created (initLoader)
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Uri uri = Uri.parse(DatabaseContentProvider.AUTHORITY + DatabaseContentProvider.TABLE_PATH_PICTURE);
CursorLoader cl = new CursorLoader(this, uri, projection, null, null, orderBy);
return cl;
}
@Override
// Called automatically when a previously created loader has finished loading
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
myAdapter.swapCursor(data);
}
@Override
// Called when a previously created loader is reset, making the data unavailable
public void onLoaderReset(Loader<Cursor> loader) {
myAdapter.swapCursor(null);
}
}
这是我创建的ContentProvider:
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
public class DatabaseContentProvider extends ContentProvider {
//database
private DatabaseAssetHelper dbhelper;
//stuff
public static final String AUTHORITY = "com.frlnrl.myapp.DatabaseContentProvider";
public static final String TABLE_PATH_PICTURE = DatabaseContract.Pictures.TABLE_PICTURE;
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
//UriMatcher
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
sURIMatcher.addURI(AUTHORITY, TABLE_PATH_PICTURE , 37);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
int numberOfLinesDeleted = 0;
return numberOfLinesDeleted;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean onCreate() {
dbhelper = new DatabaseAssetHelper(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
SQLiteDatabase db = dbhelper.getReadableDatabase();
int uriReceived = sURIMatcher.match(uri);
switch (uriReceived) {
case 37:
if (TextUtils.isEmpty(sortOrder)) sortOrder = "_ID ASC";
queryBuilder.setTables(DatabaseContract.Pictures.TABLE_PICTURE);
break;
default:
throw new IllegalArgumentException("Unknown oh eu aqui URI");
}
Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
int numberOfLineUpdated = 0;
return numberOfLineUpdated;
}
}
有没有人知道为什么返回一个空光标?
答案 0 :(得分:2)
首先,您应该为您的路径修复CONTENT_URI
。
变化
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
到
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_PATH_PICTURE);
您未在Uri
上添加路径。
然后在创建游标加载器时,你可以使用CONTENT_URI,而不是每次尝试解析Uri
(你做错了导致你的游标加载器试图查询不存在的Uri并返回一个空游标)
@Override
// Called when a new Loader needs to be created (initLoader)
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Uri uri = DatabaseContentProvider.CONTENT_URI;
CursorLoader cl = new CursorLoader(this, uri, projection, null, null, orderBy);
return cl;
}