LONGMAN
LONGMAN

Reputation: 990

Android Retrofit2/RxJava2/Room - Simple Data Processing

I am working on the application, where on the application startup I am downloading categories and posts from Rest service for storing them in the SQLite database. I have a few questions:

  1. How can I determine which object is Category and which Post? Or how can I access them at all? objects variable is pretty strange.
  2. Where I should put the code for inserting items in the database using Room library?
  3. I need to download images for each post, where I should do so?

Code:

ItemsApi client = this.getClient(); // Retrofit2

List<Observable<?>> requests = new ArrayList<>();
requests.add(client.getCategories());
requests.add(client.getPosts());

Observable<Object> combined = Observable.zip(
        requests,
        new Function<Object[], Object>() {
            @Override
            public Object apply(Object[] objects) throws Exception {
                Timber.d("Length %s", objects.length); // Length 2
                Timber.d("objects.getClass() %s", objects.getClass()); // objects.getClass() class [Ljava.lang.Object;

                return new Object();
            }
        });

Disposable disposable = combined.subscribe(
        new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {
               Timber.d("Object %s", o.toString());
            }
        },

        new Consumer<Throwable>() {
            @Override
            public void accept(Throwable e) throws Exception {
                Timber.d("error: %s", e.toString());
            }
        }
);


private ItemsApi getClient() {
    Retrofit.Builder builder = new Retrofit
            .Builder()
            .client(this.getOkHttpClient())
            .addConverterFactory(GsonConverterFactory.create(this.getGson()))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
            .baseUrl(Config.WEBSERVICE_URL_PREFIX);

    return builder.build().create(ItemsApi.class);
}

ItemsApi.class:

public interface ItemsApi {
    @GET("categories")
    Observable<List<CategoryEntity>> getCategories();

    @GET("posts")
    Observable<List<ArticleEntity>> getPosts();
}

Upvotes: 2

Views: 409

Answers (2)

Misha Akopov
Misha Akopov

Reputation: 13027

Here are answers:

1) For parallel requests, you should use Observable.zip, like this

Observable<Boolean> obs = Observable.zip(
    client.getCategories(),
    client.getPosts(), 
    (categoriesList, postsList) -> {
         // you have here both categories and lists
         // write any code you like, for example inserting to db
         return true;
});

Here you have parameters (categoriesList, postsList) each of its types, List and List.

2) You should put your code where I specified in comments. Make sure you have it in correct Thread

3) Downloading images could also be done there. You can have another zip-s in the function, combining parallel downloading images, insertions to db etc. All of them should be observables, combined with zip.

In zip you can combine as many observables, as you wish, their results will be available as combining function's parameters.

Upvotes: 5

Phong Nguyen
Phong Nguyen

Reputation: 7097

1._ Did you try addConverterFactory of Retrofit?

Retrofit restAdapter = new Retrofit.Builder().baseUrl("https://abc")
                .addConverterFactory(GsonConverterFactory.create(new Gson()))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        RestAuthenticationService restAuthenticationService = restAdapter.create(RestAuthenticationService.class);

In RestAuthenticationService.class:

public interface RestAuthenticationService {

    @POST("security/login")
    Observable<User> login(@Body LoginRequest loginRequest);

}
  1. You mean handle caching data at local? I think you should use Realm instead of Room/native SQLite.

  2. You should use Picasso or Glide.

Upvotes: 1

Related Questions