我正在使用Retrofit 2 + RxAndroid,这个代码在Marshmallow和Lollipop设备上运行很好,但是没有使用kitkat设备。
@OnClick(R.id.login_btn)
public void onLoginClicked() {
loginBtn.setEnabled(false);
AuthenticationAPI authApi = ServiceCreator.createService(AuthenticationAPI.class, null);
authApi.login(new LoginUserRequest(emailEditText.getText().toString(), passwordEditText.getText().toString()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(verifyEmailResponse -> Log.i("TEST", "onNext: " + verifyEmailResponse.success),
throwable -> {
handleError(throwable);
loginBtn.setEnabled(true);
});
}
ServiceCreator.java
public class ServiceCreator {
private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
private static final int DEFAULT_TIMEOUT = 30; //seconds
private static Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss").create();
private static RxJavaCallAdapterFactory rxAdapter = RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io());
private static Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(BuildConfig.REST_BASE_ENDPOINT)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(rxAdapter);
public static <RESTService> RESTService createService(Class<RESTService> service, String userToken) {
if (BuildConfig.REST_DEBUG) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(logging);
}
if (StringUtils.isNotBlank(userToken)) {
httpClient.addInterceptor(chain -> {
Request original = chain.request();
Request request = original.newBuilder()
.header(Constants.AUTHORIZATION_HEADER, userToken)
.method(original.method(), original.body())
.build();
return chain.proceed(request);
});
}
httpClient.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
httpClient.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
httpClient.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
Retrofit retrofit = builder.client(httpClient.build()).build();
return retrofit.create(service);
}
public static Retrofit retrofit() {
return builder.client(httpClient.build()).build();
}
}
错误:
FATAL EXCEPTION: RxNewThreadScheduler-1 java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:59)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.StackOverflowError
at org.apache.harmony.security.asn1.ASN1StringType.getDecodedObject(ASN1StringType.java:99)
at org.apache.harmony.security.asn1.ASN1StringType.decode(ASN1StringType.java:90)
at org.apache.harmony.security.asn1.ASN1Choice.decode(ASN1Choice.java:308)
at org.apache.harmony.security.x501.AttributeTypeAndValue$1.decode(AttributeTypeAndValue.java:339)
at org.apache.harmony.security.asn1.BerInputStream.readSequence(BerInputStream.java:554)
at org.apache.harmony.security.asn1.DerInputStream.readSequence(DerInputStream.java:105)
at org.apache.harmony.security.asn1.ASN1Sequence.decode(ASN1Sequence.java:40)
at org.apache.harmony.security.asn1.BerInputStream.decodeValueCollection(BerInputStream.java:626)
at org.apache.harmony.security.asn1.BerInputStream.readSetOf(BerInputStream.java:606)
at org.apache.harmony.security.asn1.DerInputStream.readSetOf(DerInputStream.java:115)
at org.apache.harmony.security.asn1.ASN1SetOf.decode(ASN1SetOf.java:40)
at org.apache.harmony.security.asn1.BerInputStream.decodeValueCollection(BerInputStream.java:626)
at org.apache.harmony.security.asn1.BerInputStream.readSequenceOf(BerInputStream.java:584)
at org.apache.harmony.security.asn1.ASN1SequenceOf.decode(ASN1SequenceOf.java:40)
at org.apache.harmony.security.asn1.ASN1Type.decode(ASN1Type.java:82)
at javax.security.auth.x500.X500Principal.<init>(X500Principal.java:78)
at com.android.org.conscrypt.OpenSSLX509Certificate.getIssuerX500Principal(OpenSSLX509Certificate.java:422)
at com.android.org.conscrypt.OpenSSLX509Certificate.getIssuerDN(OpenSSLX509Certificate.java:236)
at com.android.org.conscrypt.TrustManagerImpl.cleanupCertChainAndFindTrustAnchors(TrustManagerImpl.java:340)
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:225)
at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:202)
at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:611)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:405)
at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:241)
at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:198)
at okhttp3.internal.connection.RealConnection.buildConnection(RealConnection.java:174)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:114)
at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:193)
at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:129)
at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:98)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:67)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:109)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:92)
谢谢!
//更新:我发现了导致错误的原因而不是解决方案,我在https://github.com/square/okhttp/issues/2962中创建了一个问题
答案 0 :(得分:1)
发生错误是因为我一遍又一遍地添加相同的拦截器,新版本可能是。
public class ServiceCreator {
private OkHttpClient.Builder httpClient;
private static final int DEFAULT_TIMEOUT = 30; //seconds
private Gson gson;
private RxJavaCallAdapterFactory rxAdapter;
private Retrofit.Builder builder;
private static ServiceCreator mInstance = null;
private ServiceCreator() {
httpClient = new OkHttpClient.Builder();
gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss").create();
rxAdapter = RxJavaCallAdapterFactory.createWithScheduler(Schedulers.io());
builder = new Retrofit.Builder()
.baseUrl(BuildConfig.REST_BASE_ENDPOINT)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(rxAdapter);
if (BuildConfig.REST_DEBUG) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(logging);
}
}
public static ServiceCreator getInstance() {
if (mInstance == null) {
mInstance = new ServiceCreator();
}
return mInstance;
}
public <RESTService> RESTService createService(Class<RESTService> service, String userToken) {
if (StringUtils.isNotBlank(userToken)) {
httpClient.addInterceptor(chain -> {
Request original = chain.request();
Request request = original.newBuilder()
.header(Constants.AUTHORIZATION_HEADER, userToken)
.method(original.method(), original.body())
.build();
return chain.proceed(request);
});
}
httpClient.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
httpClient.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
httpClient.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
Retrofit retrofit = builder.client(httpClient.build()).build();
return retrofit.create(service);
}
public Retrofit retrofit() {
return getInstance().builder.client(getInstance().httpClient.build()).build();
}
}
答案 1 :(得分:0)
这是处理OkHttp和改造的最微不足道的问题之一。实际上,我也在努力争取解决方案很长一段时间,直到我因为下面的代码块而导致错误。
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(logging);
因此,一旦删除了线条,就应该正常工作。