android - Retrofit + rxandroid causes stackoverflow error on kitkat -
i working retrofit 2 + rxandroid, code works pefect on marshmallow , lollipop devices, fails kitkat devices.
@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(); } }
the error:
fatal exception: rxnewthreadscheduler-1 java.lang.illegalstateexception: fatal exception thrown on scheduler.worker thread. @ rx.internal.schedulers.scheduledaction.run(scheduledaction.java:59) @ java.util.concurrent.executors$runnableadapter.call(executors.java:422) @ java.util.concurrent.futuretask.run(futuretask.java:237) @ java.util.concurrent.scheduledthreadpoolexecutor$scheduledfuturetask.access$201(scheduledthreadpoolexecutor.java:152) @ java.util.concurrent.scheduledthreadpoolexecutor$scheduledfuturetask.run(scheduledthreadpoolexecutor.java:265) @ java.util.concurrent.threadpoolexecutor.runworker(threadpoolexecutor.java:1112) @ java.util.concurrent.threadpoolexecutor$worker.run(threadpoolexecutor.java:587) @ java.lang.thread.run(thread.java:841) caused by: java.lang.stackoverflowerror @ org.apache.harmony.security.asn1.asn1stringtype.getdecodedobject(asn1stringtype.java:99) @ org.apache.harmony.security.asn1.asn1stringtype.decode(asn1stringtype.java:90) @ org.apache.harmony.security.asn1.asn1choice.decode(asn1choice.java:308) @ org.apache.harmony.security.x501.attributetypeandvalue$1.decode(attributetypeandvalue.java:339) @ org.apache.harmony.security.asn1.berinputstream.readsequence(berinputstream.java:554) @ org.apache.harmony.security.asn1.derinputstream.readsequence(derinputstream.java:105) @ org.apache.harmony.security.asn1.asn1sequence.decode(asn1sequence.java:40) @ org.apache.harmony.security.asn1.berinputstream.decodevaluecollection(berinputstream.java:626) @ org.apache.harmony.security.asn1.berinputstream.readsetof(berinputstream.java:606) @ org.apache.harmony.security.asn1.derinputstream.readsetof(derinputstream.java:115) @ org.apache.harmony.security.asn1.asn1setof.decode(asn1setof.java:40) @ org.apache.harmony.security.asn1.berinputstream.decodevaluecollection(berinputstream.java:626) @ org.apache.harmony.security.asn1.berinputstream.readsequenceof(berinputstream.java:584) @ org.apache.harmony.security.asn1.asn1sequenceof.decode(asn1sequenceof.java:40) @ org.apache.harmony.security.asn1.asn1type.decode(asn1type.java:82) @ javax.security.auth.x500.x500principal.<init>(x500principal.java:78) @ com.android.org.conscrypt.opensslx509certificate.getissuerx500principal(opensslx509certificate.java:422) @ com.android.org.conscrypt.opensslx509certificate.getissuerdn(opensslx509certificate.java:236) @ com.android.org.conscrypt.trustmanagerimpl.cleanupcertchainandfindtrustanchors(trustmanagerimpl.java:340) @ com.android.org.conscrypt.trustmanagerimpl.checktrusted(trustmanagerimpl.java:225) @ com.android.org.conscrypt.trustmanagerimpl.checkservertrusted(trustmanagerimpl.java:202) @ com.android.org.conscrypt.opensslsocketimpl.verifycertificatechain(opensslsocketimpl.java:611) @ com.android.org.conscrypt.nativecrypto.ssl_do_handshake(native method) @ com.android.org.conscrypt.opensslsocketimpl.starthandshake(opensslsocketimpl.java:405) @ okhttp3.internal.connection.realconnection.connecttls(realconnection.java:241) @ okhttp3.internal.connection.realconnection.establishprotocol(realconnection.java:198) @ okhttp3.internal.connection.realconnection.buildconnection(realconnection.java:174) @ okhttp3.internal.connection.realconnection.connect(realconnection.java:114) @ okhttp3.internal.connection.streamallocation.findconnection(streamallocation.java:193) @ okhttp3.internal.connection.streamallocation.findhealthyconnection(streamallocation.java:129) @ okhttp3.internal.connection.streamallocation.newstream(streamallocation.java:98) @ okhttp3.internal.connection.connectinterceptor.intercept(connectinterceptor.java:42) @ okhttp3.internal.http.realinterceptorchain.proceed(realinterceptorchain.java:92) @ okhttp3.internal.http.realinterceptorchain.proceed(realinterceptorchain.java:67) @ okhttp3.internal.cache.cacheinterceptor.intercept(cacheinterceptor.java:109) @ okhttp3.internal.http.realinterceptorchain.proceed(realinterceptorchain.java:92)
thanks!
//update: have discovered cause error not solution, have created issue in https://github.com/square/okhttp/issues/2962
the error happens because adding same interceptor on , over, new version be.
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(); } }
Comments
Post a Comment