Модифицированный обратный вызов в главном потоке

С вызовом как:

@GET("/user/{id}/data")
void getUserData(@Path("id") int id, Callback<Data> cb);

Предполагается, что обратный вызов выполняется в основном потоке (если не используется RxJava). Мои вопросы:

  1. Где происходит синтаксический анализ (предположим, я использую конвертер XML для ответа процесса). Это основной поток или другой? Зависит ли это от реализации конвертера?
  2. Если мне нужно включить некоторые (тяжелые) правила проверки / бизнес-правила, нужно ли создавать новый поток внутри вызываемого объекта? Или это нормально делать в методах обратного вызова?

Я ищу способы получения данных в своей деятельности из веб-службы, избегая самостоятельного управления потоками (или использую другие подходы, такие как IntentService и т. Д.), Но боюсь также использовать RxJava (из-за экспериментальной поддержки). Есть ли другой предлагаемый подход для решения этой проблемы?

1 ответ

Решение

Где происходит синтаксический анализ (предположим, я использую конвертер XML для ответа процесса). Это основной поток или другой? Зависит ли это от реализации конвертера?

Всегда фоновый поток независимо от того, какой конвертер вы используете.

Если мне нужно включить некоторые (тяжелые) правила проверки / бизнес-правила, нужно ли создавать новый поток внутри вызываемого объекта? Или это нормально делать в методах обратного вызова?

Это довольно субъективно, и есть много способов справиться с этим. Callback будет выполняться в главном потоке по умолчанию.

Вы можете изменить поток, в котором будут вызываться обратные вызовы, предоставив пользовательский Executor к RestAdapter.Builder, Это повлияет на все сервисы, созданные этим RestAdapterОднако, это может быть не то, что вы хотите.

Нет ничего плохого в том, чтобы порождать другой поток (или ставить в очередь на исполнителя) из Callback если работа, которую вы хотите выполнить, может выполняться параллельно с обновлением пользовательского интерфейса (например, облегченное кэширование).

Если перед уведомлением пользовательского интерфейса необходимо выполнить дорогостоящую работу, лучше переключить метод на синхронный (без обратного вызова) и выполнить потоковую обработку самостоятельно. Таким образом, вы можете выполнять дорогостоящие операции до и после HTTP-вызова (файловый ввод / вывод, кэширование, преобразование, проверка и т. Д.).

В настоящее время мы используем RxJava (экспериментальная поддержка которого Retrofit) для того, что вы просите:

interface Foo {
  @GET("/")
  Observable<Foo> getFoo(String bar);
}

foo.getFoo()
  .mapMany(new ExpensiveOperationFunction())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(new Observer<TransformedFoo>() { .. });
Другие вопросы по тегам