繁体   English   中英

游标加载是基于片段加载,而不是数据更改

[英]Cursor loads on fragment load, not on data change

我无法弄清楚为什么在插入新行时未调用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;
    }
}

AlertProvider:

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

第十遍之后,我发现我没有在AlertProvider.query方法的末尾调用cursor.setNotificationUri(getContext().getContentResolver(), uri) 添加该行可确保光标找到了新插入的数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM