我无法弄清楚为什么在插入新行时没有调用onLoadFinished
。我已确认以下
在片段中:
public class AlertListFragment extends Fragment
implements LoaderManager.LoaderCallbacks<Cursor> {
private static final int ALERT_LOADER_ID = 7;
private AlertAdapter alertAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
alertAdapter = new AlertAdapter(getActivity(), new ArrayList<Alert>());
...
}
@Override
public void onActivityCreated(@Nullable Bundle bundle) {
super.onActivityCreated(bundle);
getLoaderManager().initLoader(ALERT_LOADER_ID, null, this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch(id) {
case ALERT_LOADER_ID:
AlertTable table = new AlertTable();
Uri uri = // equivalent to content://my.foo/alert
Log.d("Creating CursorLoader for " + uri);
String[] columns = {"a", "b", "c"}
return new CursorLoader(getActivity(), uri, columns, null, null, "a ASC");
default:
throw new IllegalArgumentException("Do not recognise cursor loader of type " + id);
}
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
Log.d("There's new data!!");
if (data.moveToFirst()) {
alertAdapter.clear();
do {
Alert alert = // code to parse alert from data
alertAdapter.add(alert);
} while (data.moveToNext());
alertAdapter.notifyDataSetChanged();
}
}
AlertAdapter:
public class AlertAdapter extends ArrayAdapter<Alert> {
public AlertAdapter(Context context, List<Alert> items) {
super(context, R.layout.alert_item, items);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.alert_item, parent, false);
TextView labelView = (TextView) rowView.findViewById(R.id.temporary);
labelView.setText(getItem(position).toString());
return rowView;
}
}
警报提供者:
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteDatabase db = dbFactory.getReadableDatabase();
Cursor cursor;
switch (getPath(uri)) {
case Alerts:
cursor = db.query(AlertTable._name, projection, selection, selectionArgs, null, null, sortOrder);
break;
default:
throw new UnsupportedOperationException("Not yet implemented: select from " + uri);
}
Log.d(format("Found %d %s", cursor.getCount(), uri.toString()));
return cursor;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
SQLiteDatabase db = dbFactory.getWritableDatabase();
Uri resultUri;
switch (getPath(uri)) { // getPath encapsulates matching Uri and converting to enum
case Alerts:
resultUri = insertInto(db, uri, alertTable, values);
break;
default:
throw new UnsupportedOperationException("Not implemented: insert into " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
Log.d(format("Inserted %s. Notified %s", resultUri, uri));
return resultUri;
}
最后,日志:
启动时:
D/FXAlerts( 2754): Creating CursorLoader for content://my.foo/alert
D/FXAlerts( 2754): Found 5 content://my.foo/alert
D/FXAlerts( 2754): There's new data!!
插入my.foo
项目时:
Inserted content://myfoo/alert/a/b. Notified content://my.foo/alert
并且日志显示插入后没有调用onLoadFinished
,尽管getContext().getContentResolver().notifyChange(uri, null);
答案 0 :(得分:1)
经过第10次,我发现在cursor.setNotificationUri(getContext().getContentResolver(), uri)
方法结束时我没有调用AlertProvider.query
。添加该行可确保光标找到新插入的数据。