Android: успешный и неудачный обратный вызов дооснащения выполняется асинхронно?

Сегодня я как раз проводил исследование по модернизации нашего собственного Джейка Уортона, поэтому я сделал что-то вроде этого.

RetroClass.getClient().getSomeData(param, new Callback<Model>(){

@Override 
public void failure(...){/*blah*/}

@Override
public void success(Model response, Response notUsed)
{
try
{
  Thread.sleep(10000);
}
catch(Exception e){e.pST();}
}}); 

Я ожидал ANR, но поток выполняется нормально, Джейк Уортон упомянул в этом сообщении Выполняет ли Retrofit сетевые вызовы в основном потоке? "Как указано в ответе, если вы используете второй шаблон (последний аргумент в качестве обратного вызова), запрос выполняется асинхронно, но обратный вызов вызывается в основном потоке. По умолчанию Retrofit использует пул потоков для этих запросов».

что обратный вызов выполняется в основном потоке, что здесь происходит, какие-либо идеи? Почему Thread.sleep() не вызывает ANR здесь...? Я сбит с толку....


person uLYsseus    schedule 21.10.2014    source источник


Ответы (1)


Да, по умолчанию для платформы Android используется Callback Executor MainThreadExecutor.

Убедитесь, что вы не переопределяете реализацию по умолчанию при создании RestAdapter, выполнив что-то вроде этого

RestAdapter restAdapter = new RestAdapter.Builder()
            .setExecutors(new MyHttpExecuter(), new MyCallbackExecutor()) { // watch out for this
            .build()

Если вы переопределите Callback Executor по умолчанию, установив свои собственные, вы не получите поведение по умолчанию.

person Miguel    schedule 21.10.2014
comment
и это почти как создать новую тему, верно? за исключением того, что вы используете Executor .. вместо явного вызова new Thread (new (ThreadRunnable ())) и его запуска? - person uLYsseus; 22.10.2014
comment
На самом деле мой ответ не кажется решением вашего вопроса. В случае, когда вы НЕ переопределяете обратный вызов по умолчанию, вы будете использовать MainThreadScheduler, что означает, что любая блокировка, выполненная из обратного вызова onSuccess или onFailure, заблокирует пользовательский интерфейс. Даже если вы на самом деле не получаете ANR, вы должны проверить, чтобы увидеть, что вы, вероятно, заметите, что пользовательский интерфейс блокируется во время выполнения вашего обратного вызова. Вы даже можете поставить точку останова в обратном вызове onSuccess и посмотреть на поток, в котором он выполняется, используя вашу IDE. - person Miguel; 22.10.2014
comment
И да! Интерфейс Executer позволяет отделить отправку задачи от механики выполнения каждой задачи, включая сведения об использовании потоков, планировании и т. д. docs.oracle.com/javase/7/docs/api/java/util/concurrent/ - person Miguel; 22.10.2014