How to "wait" for data from API - android

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

Related

Retrofit add Okhttp interceptor no use

I found something strange when I add interceptor like this:
public ApiDefinition getService() {
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(chain -> {
System.out.println("into interceptor");
Request request = chain.request();
return chain.proceed(request);
})
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(UrlConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
.build();
return retrofit.create(ApiDefinition.class);
}
Then when I do call a network, nothing print just like the interceptor did't work.
Observable observable = apiDefinition.getResponse();
observable.subscribe(....)
I am confused, was there anything wrong?
apiDefinition.getResponse(); you forgetting to subscribe api call. Just getting observable, but not observing it.
apiDefinition
.getResponse()
.subscribe(.......);
if you want to intercept Network request call and print them in logcat
you can do so by adding an HttpLoggingInterceptor like that:
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
// set your desired log level
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(logging)
.build();
Sorry guys, i make some mistakes when i user dagger2 to inject ApiDefinition, so this is solved.

Retrofit: Can I re-use OkhttpClient?

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"?

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 :)

Is possible to use multiple retrofit API

I am using retrofit 2. I need to use 2 different Rest API, because they have different base URL, headers and cookies.
public class RestClient {
private static IRestApi REST_CLIENT;
static {
setupRestClient();
}
public static IRestApi get() {
return REST_CLIENT;
}
private static void setupRestClient() {
Interceptor interceptor = new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
//add some cookies & headers
}
};
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(GenericConstants.READ_TIMEOUT, TimeUnit.SECONDS)
.connectTimeout(GenericConstants.CONNECTION_TIMEOUT, TimeUnit.SECONDS)
.addInterceptor(interceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(GenericConstants.BASE_ENDPOINT_INSTAGRAM)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
REST_CLIENT = retrofit.create(IRestApi.class);
}
}
I am using it like so:
Call<Obj> call = RestClient.get().myMethod(params);
I want to create 2 clases like this, because I have 2 types of requests, 1 with headers and cookies and one plain, is this possible?
you can create method of retrofit url like
public Retrofit getAdapter(String url){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
return retrofit;
}
Use this adapter wherever you want.

Logging a Response using Retrofit 2

I need to log the response my server is sending after a call, because I am receiving a MalformedJsonException, to see what is going on.
I am using this code:
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor() {
#Override
public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
com.squareup.okhttp.Response respuesta = chain.proceed(chain.request());
Log.i("David", "Response: "+respuesta.toString());
return response;
}
});
Retrofit builder = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build()
.client(client);
I have done this following this tutorial. I get an error in ".client(client); line: "client() in Retrofit cannot be applied to (com.squareup.okhttp.OkHttpClient)
What I am doing wrong? What do I need to do to intercept the response from the server, to see what's wrong with the JSON?
Thank you.
client(OkHttpClient) is a method of Retrofit.Builder() not of Retrofit. Change
Retrofit builder = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build()
.client(client);
with
Retrofit builder = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build() ;

Categories

Resources