Этот вопрос относится к пакетной операции с поставщиком контента. Пример изменен из этого связанного вопроса.
При создании пакета операций сначала создайте список операций для выполнения, используя:
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/#/бар
Сейчас мы просто вставим 2 новые записи 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.
person
Moog
schedule
19.07.2011