Я пытаюсь выполнить синхронный запрос на мой сервер в Android. (Код работает безупречно в простом Java-проекте)Ошибка Retrofit 2: NetworkOnMainThreadException
Я знаю, что запросы синхронизации не должны выполняться в основном потоке, поэтому я начинаю новый поток, где сетевое взаимодействие выполняется. Я также знаю, что можно делать асинхронные вызовы, но вызов синхронизации лучше подходит для меня.
bool networkingIsDoneHere(){
dostuff();
int number = doNetworkCall();
if(number < 500){
return true;
}
return false
}
Проблема в том, что я все еще получаю сообщение об ошибке «NetworkOnMainThreadException». Переоборудовать ли каким-то образом на основной поток, выполняя на боковой нитке?
Запуск нового потока:
Thread timerThread = new Thread() {
@Override
public void run() {
while (true) {
try {
networkingIsDoneHere();
sleep(getExecutionInterval());
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
@Override
public void startRule() {
timerThread.start();
}
код дооснащения
private Retrofit createRetrofitAdapter() throws Exception {
return retrofit = new Retrofit.Builder()
.baseUrl("https://maps.googleapis.com/maps/api/")
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public interface ApiGoogleMapsService {
@GET("url...")
Call<MapApiCall> getDurationJson(@Query("origins") String origin, @Query("destinations") String destination);
}
ошибка:
Caused by: android.os.NetworkOnMainThreadException
be.kul.gj.annotationfw W/System.err: at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1273)
be.kul.gj.annotationfw W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.shutdownAndFreeSslNative(OpenSSLSocketImpl.java:1131)
be.kul.gj.annotationfw W/System.err: at com.android.org.conscrypt.OpenSSLSocketImpl.close(OpenSSLSocketImpl.java:1126)
be.kul.gj.annotationfw W/System.err: at okhttp3.internal.Util.closeQuietly(Util.java:105)
be.kul.gj.annotationfw W/System.err: at okhttp3.internal.http.StreamAllocation.deallocate(StreamAllocation.java:260)
be.kul.gj.annotationfw W/System.err: at okhttp3.internal.http.StreamAllocation.connectionFailed(StreamAllocation.java:289)
be.kul.gj.annotationfw W/System.err: at okhttp3.internal.http.HttpEngine.close(HttpEngine.java:429)
be.kul.gj.annotationfw W/System.err: at okhttp3.RealCall.getResponse(RealCall.java:270)
be.kul.gj.annotationfw W/System.err: at okhttp3.RealCall$ApplicationInterceptorChain.proceed(RealCall.java:198)
be.kul.gj.annotationfw W/System.err: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:160)
be.kul.gj.annotationfw W/System.err: at okhttp3.RealCall.execute(RealCall.java:57)
be.kul.gj.annotationfw W/System.err: at retrofit2.OkHttpCall.execute(OkHttpCall.java:177)
be.kul.gj.annotationfw W/System.err: at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:87)
be.kul.gj.annotationfw W/System.err: at model.GoogleMapsAccess.getTravelDuration(GoogleMapsAccess.java:52)
be.kul.gj.annotationfw W/System.err: at rule.RoutePickupRule.condition(RoutePickupRule.java:40)
В моем примере я добавил «networkingIsDoneHere». Это показывает, почему я не хочу использовать это решение. Мне нужен результат моего сетевого вызова в моем «if case» и возвращает true для false. –
Извините, я, должно быть, неправильно понял. Вы используете 'execute()' в своем потоке? Я обновил свой ответ. –
Думаю, я нашел свою проблему. Я вызываю код где-то еще из основного потока с помощью Handler с Runnable, но это, похоже, не работает в отдельном потоке. Я собираюсь принять твое мнение, потому что это хорошее объяснение общей концепции :) –