Какова семантика withValueBackReference? - PullRequest
38 голосов
/ 11 января 2011

Я не могу понять точную семантику с помощью ValueBackReference .

Я прочитал пример кода (например, код, который добавляет новый контакт), используя этот метод, предоставив значение backReference, равное 0. Что это значит?

В документации сказано:

Значение столбца из обратных ссылок имеет приоритет над значением, указанным в withValues ​​(ContentValues)

1 Ответ

162 голосов
/ 19 июля 2011

Этот вопрос относится к пакетной операции с поставщиком контента. Пример изменен с на этот связанный вопрос .

При создании пакета операций сначала создайте список операций, которые нужно выполнить, используя:

ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();

затем примените их к поставщику контента, используя метод applyBatch.

ContentProviderResult[] results = this.getContentResolver().applyBatch(FooBar.AUTHORITY, operations);

Это базовая концепция, поэтому давайте ее применим. Предположим, у нас есть поставщик контента, который обрабатывает uris для записей Foo и некоторых дочерних записей, называемых Bar.

Содержание: //com.stackoverflow.foobar/foo

содержание: //com.stackoverflow.foobar/foo/#/bar

А пока мы просто вставим две новые записи Foo с именами "Foo A" и "Foo B", вот пример.

ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();

//add a new ContentProviderOperation - inserting a FOO record with a name and a decscription
operations.add(ContentProviderOperation.newInsert(intent.getData())
    .withValue(FOO.NAME, "Foo A")
    .withValue(FOO.DESCRIPTION, "A foo of impeccable nature")
    .build());

//let's add another
operations.add(ContentProviderOperation.newInsert(intent.getData())
    .withValue(FOO.NAME, "Foo B")
    .withValue(FOO.DESCRIPTION, "A foo of despicable nature")
    .build());

ContentProviderResult[] results = this.getContentResolver().applyBatch(FooBar.AUTHORITY, operations);

Ничего особенного, мы добавляем 2 элемента ContentProviderOperation в наш список, а затем применяем этот список к нашему поставщику контента. Массив результатов заполнен идентификаторами новых записей, которые мы только что вставили.

Допустим, мы хотели сделать что-то подобное, но мы также хотим добавить несколько дочерних записей в наш контент-провайдер за одну пакетную операцию. Мы хотим прикрепить дочерние записи к только что созданным записям Foo. Проблема в том, что мы не знаем идентификатор родительских записей Foo, потому что пакет не был запущен. Именно здесь нам помогает withValueBackReference. Давайте посмотрим пример:

ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>();

//add a new ContentProviderOperation - inserting a Foo record with a name and a decscription
operations.add(ContentProviderOperation.newInsert(intent.getData())
    .withValue(FOO.NAME, "Foo A")
    .withValue(FOO.DESCRIPTION, "Foo of impeccable nature")
    .build());

//let's add another
operations.add(ContentProviderOperation.newInsert(intent.getData())
    .withValue(FOO.NAME, "Foo B")
    .withValue(FOO.DESCRIPTION, "Foo of despicable nature")
    .build());

//now add a Bar record called [Barbarella] and relate it to [Foo A]
operations.add(ContentProviderOperation.newInsert(intent.getData()
    .buildUpon()
    .appendPath("#") /* We don't know this yet */
    .appendPath("bar")
    .build())
.withValueBackReference (BAR.FOO_ID, 0) /* Index is 0 because Foo A is the first operation in the array*/
.withValue(BAR.NAME, "Barbarella")
.withValue(BAR.GENDER, "female")
.build());

//add a Bar record called [Barbarian] and relate it to [Foo B]
operations.add(ContentProviderOperation.newInsert(intent.getData()
    .buildUpon()
    .appendPath("#") /* We don't know this yet */
    .appendPath("bar")
    .build())
.withValueBackReference (BAR.FOO_ID, 1) /* Index of parent Foo B is 1*/
.withValue(BAR.NAME, "Barbarian")
.withValue(BAR.GENDER, "male")
.build());

ContentProviderResult[] results = this.getContentResolver().applyBatch(FooBar.AUTHORITY, operations);

Таким образом, метод withValueBackReference () позволяет нам вставлять связанные записи, прежде чем мы узнаем идентификатор родителя, с которым мы хотим связать их. Индекс обратной ссылки - это просто индекс операции, которая возвращает идентификатор, который мы хотим найти. Возможно, проще думать об этом с точки зрения того, какой результат вы ожидаете содержать идентификатор. например, results[1] будет содержать идентификатор для "Foo B", поэтому индекс, который мы используем для обратной ссылки на "Foo B", равен 1.

...