ich Berichte über eine NetworkOnMainThread Ausnahme auf Lollipop bekommen +, wenn ein https
api Anruf Retrofit
und RxAndroid
mit ausgeführt wird.NetworkOnMainThread RxJava + Retrofit + Lollipop +
Ich habe den Code isoliert und erstellt das folgende Beispiel, das immer noch fehlschlägt.
Hier ist der build.gradle
:
apply plugin: 'com.android.application'
apply plugin: 'me.tatarka.retrolambda'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.example.bug"
minSdkVersion 9
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt')
}
}
lintOptions {
abortOnError false
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.squareup.okhttp:okhttp:2.5.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.5.0'
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'io.reactivex:rxandroid:1.0.1'
}
Hier ist die einzige Tätigkeit:
public class HomeActivity extends Activity {
private static final String URL_BASE = "https://some.https.api.com/";
private static final String ENDPOINT = "some/endpoint";
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setConnectTimeout(15, TimeUnit.SECONDS);
okHttpClient.setReadTimeout(15, TimeUnit.SECONDS);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(URL_BASE)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(new Gson()))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
MyApi mService = retrofit.create(MyApi.class);
setContentView(R.layout.home_activity);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(v->
mService.whatever(new ParamObject())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
response -> Log.d("BUG", response.status),
error -> Log.d("BUG", error.toString()))
);
}
interface MyApi {
@POST(ENDPOINT)
Observable<ResponseObject> whatever(@Body ParamObject requirements);
}
class ResponseObject {
public String status;
}
class ParamObject {
}
}
Hier ist die Ausnahme Stacktrace:
E/AndroidRuntime(28345): FATAL EXCEPTION: main
E/AndroidRuntime(28345): Process: com.example.bug, PID: 28345
E/AndroidRuntime(28345): java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
E/AndroidRuntime(28345): at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:62)
E/AndroidRuntime(28345): at android.os.Handler.handleCallback(Handler.java:739)
E/AndroidRuntime(28345): at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime(28345): at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime(28345): at android.app.ActivityThread.main(ActivityThread.java:5221)
E/AndroidRuntime(28345): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(28345): at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime(28345): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
E/AndroidRuntime(28345): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
E/AndroidRuntime(28345): Caused by: android.os.NetworkOnMainThreadException
E/AndroidRuntime(28345): at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147)
E/AndroidRuntime(28345): at com.android.org.conscrypt.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:724)
E/AndroidRuntime(28345): at okio.Okio$1.write(Okio.java:80)
E/AndroidRuntime(28345): at okio.AsyncTimeout$1.write(AsyncTimeout.java:155)
E/AndroidRuntime(28345): at okio.RealBufferedSink.flush(RealBufferedSink.java:221)
E/AndroidRuntime(28345): at com.squareup.okhttp.internal.framed.Http2$Writer.rstStream(Http2.java:475)
E/AndroidRuntime(28345): at com.squareup.okhttp.internal.framed.FramedConnection.writeSynReset(FramedConnection.java:356)
E/AndroidRuntime(28345): at com.squareup.okhttp.internal.framed.FramedStream.close(FramedStream.java:222)
E/AndroidRuntime(28345): at com.squareup.okhttp.internal.http.FramedTransport.disconnect(FramedTransport.java:215)
E/AndroidRuntime(28345): at com.squareup.okhttp.internal.http.HttpEngine.disconnect(HttpEngine.java:573)
E/AndroidRuntime(28345): at com.squareup.okhttp.Call.cancel(Call.java:122)
E/AndroidRuntime(28345): at retrofit.OkHttpCall.cancel(OkHttpCall.java:162)
E/AndroidRuntime(28345): at retrofit.RxJavaCallAdapterFactory$CallOnSubscribe$1.call(RxJavaCallAdapterFactory.java:102)
E/AndroidRuntime(28345): at rx.subscriptions.BooleanSubscription.unsubscribe(BooleanSubscription.java:72)
E/AndroidRuntime(28345): at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124)
E/AndroidRuntime(28345): at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113)
E/AndroidRuntime(28345): at rx.Subscriber.unsubscribe(Subscriber.java:98)
E/AndroidRuntime(28345): at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124)
E/AndroidRuntime(28345): at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113)
E/AndroidRuntime(28345): at rx.Subscriber.unsubscribe(Subscriber.java:98)
E/AndroidRuntime(28345): at rx.internal.util.SubscriptionList.unsubscribeFromAll(SubscriptionList.java:124)
E/AndroidRuntime(28345): at rx.internal.util.SubscriptionList.unsubscribe(SubscriptionList.java:113)
E/AndroidRuntime(28345): at rx.Subscriber.unsubscribe(Subscriber.java:98)
E/AndroidRuntime(28345): at rx.observers.SafeSubscriber.onCompleted(SafeSubscriber.java:90)
E/AndroidRuntime(28345): at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.pollQueue(OperatorObserveOn.java:201)
E/AndroidRuntime(28345): at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber$2.call(OperatorObserveOn.java:170)
E/AndroidRuntime(28345): at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
E/AndroidRuntime(28345): ... 8 more
Ein paar Dinge:
- Dieses Codebeispiel funktioniert gut in Android 4.x
- Ich habe dieses Beispiel (mit kleinen Änderungen) gegen die GitHub API versucht und es funktioniert gut.
- Die API wird auf der App-Engine von Google ausgeführt.
- Beachten Sie, dass die beobachtbare auf
AndroidSchedulers.mainThread()
aufSchedulers.io()
und beobachtet abonnieren
Irgendwelche Ideen?
bearbeiten
Nach einem genaueren Blick auf die Stacktrace nehmen ich heraus es etwas über http2 war. Obwohl nicht das gleiche Problem gemeldet here, die folgende Zeile, um die
OkHttp
verfügbaren Protokolle zu beschränken hat es wieder funktioniert.okHttpClient.setProtocols(Collections.singletonList(Protocol.HTTP_1_1));
nur weil der editierte Teil das Problem für mich auch behoben. hatte das gleiche Problem auf Android 5.0 + – Diogo