Ответ 1
Этот вопрос относится к пакетной операции над поставщиком контента. Пример изменен из этого связанного вопроса.
При создании партии операций сначала создайте список операций для выполнения, используя:
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
Теперь мы просто вставим 2 новых Foo recordscalled "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 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 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.