How to use room database as a cache - android

I am making an android app using MVVM architecture. I want to fetch data from an API and insert it into room database and then fetch it from the room in my app. I don't know if it is a better way to implement database cache functionality. If there is some other or better way to do so please let me know.

your question explains exactly how you would use Room:
fetch data from an api
insert it into room database
fetch it from room in my app
Room allows you to store your data locally and retrieve this data with various different threads, making use of something like Rxjava, it also allows you to observe onto any changes with LiveData, Room is definitely a decent option to consider for caching
BUT
Using Room is ONE of SEVERAL different implementations of caching, consider posting code or a specific scenario for better answers. Happy coding.
Edit:
A common approach to using Room (or any caching) would be to either load initial data from the database, display this to the user, perform an api call, update the cache and display this updated data from the api
OR
If the user does not have an internet connection, simply use what he has available in the cache as data. Again, all of this depends on your specific scenario.

Related

Android Preferences DataStore vs Existing Room Implementation

I’m new to Android development and I’m about to implement simple Preferences for my app. It appears SharedPreferences is a dead end and has lots of warts, so I’m looking at DataStore (non-Proto) vs Room. Since I ALREADY heavily use Room and LiveData (yes, I know Flow is the new hotness) in my app for other things, is there any benefit to using DataStore too? I understand Room is recommended for large or complex data as I’ve already reviewed the following, but I’m hoping a more seasoned developer can further hit this home for me:
https://android-developers.googleblog.com/2020/09/prefer-storing-data-with-jetpack.html
https://proandroiddev.com/lets-explore-jetpack-datastore-in-android-621f3564b57
https://medium.com/better-programming/jetpack-datastore-improved-data-storage-system-adec129b6e48
Thank you.
The official blog post you linked has a section specifically about Room vs DataStore:
If you have a need for partial updates, referential integrity, or support for large/complex datasets, you should consider using Room instead of DataStore. DataStore is ideal for small , simple datasets and does not support partial updates or referential integrity.
User preferences almost always fall into the 'small, simple datasets' that can be easily expressed as key/value pairs (or something more complicated if you want to use the Proto DataStore) that do not need the overhead of a table schema, SQL queries, custom parsing, or the 'relational' part of a relational database.
The problem with datastore is you cannot just fetch or update a part of data from a list like you can with SQLite libraries such as Room. This is true for both Proto and Preferences version. So if you have 10 thousand elements and you save them to DataStore and then you want to update 2 of them based on a condition you'll have to fetch the entire list, manipulate it and put it back. Here Room (or any DB solution) will be a way to go
But if you just want to save user preferences or small data it would be an overkill to use a DataBase - here DataBase Proto will actually be the perfect choice

What is the best way to store app data and load it in app?

This is just a information question. I'm new to Android app development and currently I'm working on my first app and and it is ready for the release. Now I'm concerned about how to handle heap of users and where to save all their details my app is a service booking app so it needs to save all the order details products details and lots other stuff.
Currently I'm using cloud firestore to load and save all the data of app. But I'm having some issues like without authentication it won't allow users to access some of my data and other. I wonder how large apps save their data and load them perfectly.
I wish someone will help me how can I save all my app data and load them perfectly in app. And suggest me for a best way to manage large user base. And other stuff.
First of all, firestore is good option if you don't have complex backend logic on the database. For simple CRUD operations on data firestore is a good choice but as you said you have a bulk of data then you must go for the Backend database and then connect your database with Rest API. So that all your complex queries will be done on the backend and you can simply consume your API in the app.
If you have lots of data from different users, maybe you should use a central server(DB), something like Postgres or MySQL should work fine.
At the same time, you can also do some sort of caching to accelerate the fetching process, like create a small database locally(you can use Room) to store some user specific data.

For accessing data offline, better to use Room library or HTTP cache-control?

I looked into solving the problem of accessing data offline in Android and came across Room library and HTTP cache-control. I already have all of the Retrofit / OkHttp responses done in my app. Which is better to implement when there is no Internet connection?
It greatly depends on the requirements of your app.
Room allows you to save and organise the data. Specific queries and extraction of distinct objects is very powerful if needed. Besides that you can be sure the data won't be deleted, when the device needs storage and clears the cache folders. One problem however is data integrity, which would require some sort of synchroniser between your app and the backend server. I would advise you to use Room if you do any sort of data manipulation and/or want to offer certain and reliable offline user experience.
HTTP CACHE is simpler and a quite straightforward solution. You only need to add a interceptor to your OkHttp client and you are ready to go. This would be the solution if you app's main purpose is simply displaying data.

Android where to store cached data?

My app will pull some json data when it is started and realistically, once the data has been pulled, I really won't need to pull it again for the duration of the user experience. The backend data may update a few times a day at most, so I think I would like to just grab the data upon app start and then use that same data for the duration and give the user an option to manually refresh the data. So, my question is, where/how should I store that data? I've got all of my data structures set up (classes and sub-classes). And there may be 200 or so instances of some of the classes. If I store everything as member variables in my activity_main class, it won't be available to other activities once the other activities are started. Storing them all in databases could be an option, but it sort of feels like overkill. I really don't need the data to persist between sessions. Is there a way to easily store it in memory and still have it easily accessible to all activities?
You should think about OS killing your app process on low-memory, so backing your data on disk is a good thing to do. Doing so you have an ability to show user data from disk cache while refreshing it in background from server.
Choosing the tool for data storage depends on the way you need to work with data.
Of course, there is an option to use Realm, but you should consider the fact that it is not the relational database. So if you have complex domain model with joins and other relational stuff for your business logic, I'd go with something other. It is thread-safe, also has migrations (but, as for me, migrarations are always pain, you just can not do anythig about it). Realm is supposed to be RxJava-friendly now (support added in v0.87) There are some disadvantages(part of them may already be fixed), but you should consider it before using.
As for more relational approach, there is SQLBrite library:
A lightweight wrapper around SQLiteOpenHelper which introduces reactive stream semantics to SQL operations.
It is not an ORM (but you can add some kind of it on top of SQLBrite if you wish: see this for more info). In fact, being alone this library is doing one thing (and doing it good) - it provides a mechanism for coordinating and composing the notification of updates to tables(Realm also has such ability) such that you can update queries(in SQL fashion) as soon as data changes. And it respects RxJava!
As an alternative to SQLBrite you can look at StorIO.
There are also lots of different ORM solutions, like GreenDAO, ORMLite etc.
But I'm pretty sure, one of the first two libraries (Realm or SQLBrite) will likely help you. So analyze your app, these libs and decide what fits better.
P.S. Great article on how RxJava would help you to work with data from different data sources (in-memory cache + disk cache + network) easily. Might be helpful!
I would still recommend a SQLite Databse, you can easily declare it as a 'in-memory' database, if that is what you want.
However.... I would be rather upset as a user of your application if it downloaded redundant data over and over. I would just recommend making a content provider and being done with it. This gives you access to a SyncAdapter, and defines clear boundaries between where code should go.
The 'trick' with making a good ContentProvider is to make good POJOs, that have methods to convert from POJO -> ContentValues and Cursor -> POJO(s).
Easiest thing is to do is store the json file in Apps data storage and parse the json every time you need.
But this is not recommended as it is costly to parse data every time.
Best option is to implement Realm (Replacement for Sqlite) which is very easy to implement and its amazingly fast.

Do I really need Content Provider in my application

I am creating app that should have offline mode, so previously downloaded data should stored somewhere, the most common way is to store data in SQLite database.
Mostly SQLite database is used with Content Provider in android. I have clear understanding what is the purpose of content provider (to share data between different apps), but in my case application will never need to share the data with other apps in the system.
Content provider has the similar interface as HTTP request (GET,POST,PUT,DELETE).
My idea is to create facade class which can be used like this getAllLatestNews(); firstly it will try to get latest data from the internet, if it fails - data from database will be used and if request is successful it also will save retrieved data to the database. This class will be facade for separating different layers of application (not to make requests from activities directly).
But now I am a little bit puzzled deciding whenever I need Content Provider or not. I can use SQLiteOpenHelper classes to retrieve and save data to the database or even use ORM library to do this.
At first I wanted to implement REST API Pattern B by Virgil Dobjanschi. But now I am not sure about this, maybe it would be better to create facade for Robospice(in my case, network request in the service) requests and do persistence there ?
Please share you thoughts about this topic, I would be grateful for any help.
EDIT
I asked this question because I feel that it is not good practice to make requests directly from activities even if they are made in service under the hood, I want to separate different layers of my application in order to make it more flexible and maintainable.
As you don't intend to share your data, i would say that implementing a ContentProvider is overkill.
Personally im a huge fan of ORM libraries (Currently i use SugarOrm in several projects), so i would go down that road.
Then at app startup, you check whether or not you have an active internet connection, and based on that you either get the latest information online, or retrieve older information from the database.
To seperate the logic a bit, i would most likely implement the getting of online information in a service, which would then store it in the database and broadcast to the activity that the information is now available, and then the activity could retrieve the information from the newly updated database.
Content Providers are absolutely for sharing data between applications and are of no use without this purpose.
If you want to use those data only in your app privately, you could use SQLite databases. Also there other objects available:
Shared Preferences
Files
Content provider has the similar interface as HTTP request (GET,POST,PUT,DELETE)
I don't think so. It's more like to SQL language.

Categories

Resources