Retrofit: Can I re-use OkhttpClient? - android

I am developing an android app using external API servers.
Because I use 2 servers, I have 2 retrofit services.
In my "RemoteDataSource" class's constructor, I make the service objects like:
public RemoteDataSource() {
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build();
myService1 = new Retrofit.Builder()
.baseUrl(URL_1)
.client(okHttpClient)
.build()
.create(MyService1.class);
myService2 = new Retrofit.Builder()
.baseUrl(URL_2)
.client(okHttpClient) // my question is here!!!
.build()
.create(MyService2.class);
}
What I want to know is...
Can I use one "OkHttpClient" on both services?
Is there any network issue?
or Should I make another OkHttpClient object like "okHttpClient2" and assign it to "myService2"?

Related

Retrofit 2: Setting Timeouts With No Effect

i am using the following:
implementation "com.squareup.retrofit2:converter-gson:2.6.0"
fun getOkHTTPClient(time: Int, interceptor: Interceptor): OkHttpClient {
val client = OkHttpClient.Builder()
.addInterceptor(interceptor)
.connectTimeout(5, TimeUnit.SECONDS)
.writeTimeout(5, TimeUnit.SECONDS)
.readTimeout(5, TimeUnit.SECONDS)
.callTimeout(5, TimeUnit.SECONDS)
.retryOnConnectionFailure(false)
return client.build()
}
retrofit2.Retrofit.Builder()
.baseUrl("$url/")
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
If i change the timeouts to 10 seconds, 20, 50, 500 etc.... the effect is the same. the call timeout is not obeying these rules.
Am i missing something?
Note: i am using Asynchronous requests if it helps in debugging the case

How to "wait" for data from API

I have a problem,
How to wait for data from API?
I would write code like this:
List<User> userList = dataAPI.getAllUser();
I would have a list an use it wherever I want.
I don't want to Override any methods.
DataAPI:
public class DataAPI {
public DataAPI(){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
userAPI = retrofit.create(UserService.class);
public class DataAPI {
[...]
private UsertService userAPI;
public DataAPI(){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
userAPI = retrofit.create(UserService.class);
}
Observable<List<User>> getAllUser() {
return userAPI.getAllUser();
}
}
UserService
#GET("/user/all")
Observable<List<User>> getAllUser();
It could be done with rxJava, for more details: read
You just need to set timeout and increase it as you need to wait for the response coming from service. (Give priority to writeTimeout)
OkHttpClient client = new OkHttpClient.Builder();
client .connectTimeout(10, TimeUnit.SECONDS);
client .writeTimeout(30, TimeUnit.SECONDS);
client .readTimeout(40, TimeUnit.SECONDS);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.yourapp.com/")
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
#Kubek, what you need to do is subscribe to the observable.
What you should probably do is:
userAPI.getAllUser()
.subscribeOn(Schedulers.IO)
.observeOn(AndroidSchedulers.Main)
.subscribe(
// do some stuff
)
For documentation on how to use subscribe method, refer: http://reactivex.io/documentation/operators/subscribe.html

how to set retrofit connections timeout unlimited?

I want to set Retrofit connection timeout unlimited instead of static timeout
connection.how can I do it ?
This is my code...
public static Retrofit getRetrofitInstance() {
if (RetrofitInstance==null) {
Gson gson = new GsonBuilder()
.setLenient()
.create();
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(100, TimeUnit.SECONDS)
.connectTimeout(100, TimeUnit.SECONDS)
.build();
RetrofitInstance = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(okHttpClient)
.build();
}
return RetrofitInstance;
}
Retrofit does not allow developers to remove timeout completely, but you could set TimeUnit.HOURS to use big value for your timeout. For example:
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(Integer.MAX_VALUE, TimeUnit.HOURS)
.connectTimeout(Integer.MAX_VALUE, TimeUnit.HOURS)
.build();
Used Integer.MAX_VALUE for this example, which is big enough value to act as an infinite timeout.
Good luck :)

Retrofit socket timeout exception while uploading larger files using multipart

I am facing the issue of socket timeout exception while using retrofit 2.0.2 library and okhttp 2.3.0. I am trying to upload the image file which is between 500kb to 1.5mb it is uploading successfully.but when i tried to upload video file which is greater than 5mb i am getting this exception.
I used httpclient for connection settings as below.
public static OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(0, TimeUnit.SECONDS)
.writeTimeout(0, TimeUnit.SECONDS)
.readTimeout(0, TimeUnit.SECONDS)
.build();
please suggest me to upload larger files without this issue.Thanks in advance
you can provide the time in seconds as follows
public class ApiClient {
public static final String BASE_URL = "your_url";
public static Retrofit retrofit = null;
public static Retrofit getApiClient() {
if (retrofit == null) {
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build();
return new Retrofit.Builder()
.baseUrl(BASE_URL)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
i've given 60 seconds
There can be two issues with this type of error.
Check Read & Write Timeout
val client = OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build()
Check the Mime type you are sending. The backend developer may have filtered the accepted Mime type at their end. instead of MediaType.parse("multipart/form-data"). write the valid mime type for files like image/jpg or video/mp4
MediaType.parse("image/png")

HttpLoggingInterceptor not logging with retrofit 2

Im trying to log all the requests (with a network interceptor) using refrofit2, kotlin and logging-interceptor:
retrofit: "2.0.2"
okhttp3 : "3.2.0"
com.squareup.okhttp3:logging-interceptor 3.2.0
like:
val interceptor = HttpLoggingInterceptor()
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
val okHttpClient = OkHttpClient.Builder()
.addNetworkInterceptor(interceptor) // same for .addInterceptor(...)
.connectTimeout(30, TimeUnit.SECONDS) //Backend is really slow
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build()
sRestAdapter = Retrofit.Builder()
.client(okHttpClient)
.baseUrl(if (host.endsWith("/")) host else "$host/")
.addConverterFactory(GsonConverterFactory.create(gson()))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build()
It just print:
D/OkHttp: --> GET url...
D/OkHttp: --> END GET
What is happening?
--------------- EDIT --------
Errors doing requests on Main Thread are not showing by the logger, so be careful.
private val interceptor = run {
val httpLoggingInterceptor = HttpLoggingInterceptor()
httpLoggingInterceptor.apply {
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
}
}
private val okHttpClient = OkHttpClient.Builder()
.addNetworkInterceptor(interceptor) // same for .addInterceptor(...)
.connectTimeout(30, TimeUnit.SECONDS) //Backend is really slow
.writeTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build()
Instead of
val okHttpClient = OkHttpClient.Builder()
.addNetworkInterceptor(interceptor)
...
you should have something like:
val okHttpClient = OkHttpClient.Builder()
.addInterceptor(interceptor)
...
as the addNetworkInterceptor() plays with interceptors that observe a single network request and response, while addInterceptor() adds interceptor that observes the full span of each call: from the connection is established (if any) until after the response source is selected (either the origin server, cache, or both).
EDIT
Errors doing requests on Main Thread are not showing by the logger, so be careful
Doing networking on main thread is not an "ordinary" error. It will result in your app being killed by the system with NetworkOnMainThreadException and this will happen before interceptor would be given any chance to run.

Categories

Resources