游标在片段加载时加载,而不是在数据更改时加载

时间:2015-01-26 00:41:13

标签: android loader

我无法弄清楚为什么在插入新行时没有调用onLoadFinished。我已确认以下

  • 行插入正常(数据显示在应用重启时)
  • 使用与
  • 创建CursorLoader相同的Uri通知ContentResolver
  • CursorLoader在片段启动时搜索并查找数据。

在片段中:

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);

1 个答案:

答案 0 :(得分:1)

经过第10次,我发现在cursor.setNotificationUri(getContext().getContentResolver(), uri)方法结束时我没有调用AlertProvider.query。添加该行可确保光标找到新插入的数据。