0

my app architecture, quite common:

enter image description here

Please explain me if I have list of Entities, for example

@Entity(tableName = TABLE_NAME)
    class Item constructor(
            @PrimaryKey(autoGenerate = false) 
            var id: Long = 0L,
            @TypeConverters(ListToStringConverter::class)
            var eventDescription: List<String> = emptyList(),
            @TypeConverters(DateConverter::class)
            var date: Date = Date(),
            var rate: Int ?= null)

Picture explanation:

Currently I do (according to picture above):

  1. mLiveData getLiveData from Repository
  2. callbackrefreshFromDataBase()
  3. mLiveData.addSource from LiveData of DataBase - what causes that Android View is updated quickly
  4. callback refreshFromNetwork()
  5. Rest updates DatabaseTable
  6. Database insert causes that LiveData add pushes changes to the View

Formulation of the problem

What is the best practice for 5 step - a moment when new data comes and I have to replace old data with the freshest?

Currently I'm using RxJava, Room, Kotlin and I'm using in step 3 nested Rx.Single which is very ugly spagetti code.

like

disposable = usecase.getDataFromNetwork()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeBy(onSuccess = {      
                    val itemsList = it
                    dataBase.deleteAllItems()
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribeBy (onComplete = {                                                          dataBase.insertNewItems(itemsList)
                                            .subscribeOn(Schedulers.io())
                                            .observeOn(AndroidSchedulers.mainThread())
                                            .subscribeBy(onComplete = {
                                                // Process complete
                                            }, onError = {
                                                ...
                                            })
                                }
                            }, onError = {
                                ...
                            })
                }, onError = {
                    ...
                })

Ugly spagetti code.

QUESTIONS

  • Should I wipe all Table before inserting new Items? Livedata listen to the changes of List, so whenever anything changes (some item updated, some inserted, some removed) view will be updated
  • Under Circumstances where all my Streams are Single (reason: they dispose by itself when onComplete), how to chain them sequentially in oder to restrict one stream rule?
murt
  • 3,790
  • 4
  • 37
  • 48
  • If you don't understand your architecture how are we supposed to, given the limited view of the code we have? – Gabe Sechan Nov 16 '17 at 16:47
  • Just to clarify - I understand overall approach, but I wonder if anyone knows better solution to handle step 5. – murt Nov 16 '17 at 19:02

1 Answers1

0

This depends if your fetched data will be similar or not. If you fresh data is normally completly different I would delete all elements and then insert new elements with only one method like following:

@Insert
public void insertItems(Item... items);

If your new data is similar and you don't care about their order I would compare all new items to the old ones to know for each item if you have to update, insert or delete item. At the end you call deleteItems(itemsToDelete), updateItems(itemsToUpdate) and insertItems(itemsToInsert). This three methods are similar as the one written above but with @Delete, @Update and @Insert.

If you care about the order I recommend you take a look at Android Paging Library and create a custom DataSource where you can tell to your live data when to update its values. Some links to start: this, this, this and this

Damia Fuentes
  • 5,308
  • 6
  • 33
  • 65