I'm developing an app which will show some items in RecyclerView by fetching JSONs from a web service. If a user scrolls at the end of the list, more data should be fetched. For the UI, I've implemented EndlessScrollListener, but I'm not sure what would be the right option for fetching actual JSON with a proper page index (e.g. http://some.service/data&page=1). To read data from an HTTP resource, I decided to use the Volley library. If I use just Volley itself it will be a problem to handle the onConfigurationChanged event manually.
I know that AsyncTaskLoader can help me to solve my problem, but it looks like it was designed to fetch data periodically. In my case I need to load data on demand (when user scrolls down).
I also thought about implementing sync adapter to fetch data, cursor loader and content provider to save/read data in offline mode, but it looks hard for me now, because I'm an Android novice.
What can you suggest?
I'm mostly interested in architectural part of solution.
Deserialisation of json sometimes is also hard task so what you need to do is make request with volley then on result you have json string, then in async task you make deserialisation to local Object that has structure you need and only then setup view and attach final data to it. If you load list and want to make it load on scroll here is sample
Related
About Single Sources of Truth Google document said:
Using this model, the database serves as the single source of truth, and other parts of the app access it using our UserRepository. Regardless of whether you use a disk cache, we recommend that your repository designate a data source as the single source of truth for the rest of your app
https://developer.android.com/jetpack/guide?gclid=CjwKCAjwo4mIBhBsEiwAKgzXOH1Pq--Ws1PLzUiSP4RmDE6ByKfEi6mdXu5g86btqveIdJvvrgYuxBoCz8wQAvD_BwE&gclsrc=aw.ds#connect-viewmodel-repository
According to the document I save all data when I fected data from remote server and I only get data from room When I need to use in acitivty(In fact I collect flow which is defined in viewmodel).
It seems so good! It avoids the different data sources mix up together! But actually I found some strange question gradually:
In my App, I have a list that the server may change it(Because we have data manager website that admin can update or delete data). So in order to get the newest list data from server, I must clear all data stored in room and fect data again from remote server. This operation seems redundant: "why could I get data directly from remote server", I mean, I only get data from remote source is also a single sources truth. And also it cause a promble: my app will flash a moment because clear data make list empty and fect data from server make list full!
The most important thing is that it seems like the local data is not necessary because I must stay the newest list from remote server.
Some people may say that save data into room can make us app available offlice. I agree that, But in this place, my item of list is represent a image url, and after click the item, the app will jump to a new activity and display a ImageView base on the url we get from the list. If app offlice, the ImageView couldn't load the url also.
I am so confused I couldn't load all image url(use base64-url to avoid load invalid) in a moment also, because the data is so much. And if I say I need a search function in this list and I need load so much unbelievable data into my room, It seems so unreal and event fantasy!
In brief:
Room is a nessary? Couldnt just fect data from remote?
If room is nessary, how to solve problem I met, do my incorrect useage cause the problem?
Hi #psycongroo as I Understood your problem, and I want to share my experience:
You can handle any error with loading URL with placeholder I mean if you got an error with no Internet connection user will see placeholder, but in general libs like Picasso or Glide can cache images when it`s load one time, so the user will see the Image.
The question about why we need to use room instead of fetch data from remote directly. So from your question I don`t understand why you need to drop your local changes even they are completely new, user can have a low internet connection so he will see an empty list instead of previous data with for example progress indicator. And also if the user doesn't have the internet at all you can show some dialog to explain what the problem but old data is still present. If you are using, for example, RecyclerView you can update data with Paging 3 from google, and they update the only necessary items from your list.
P.S. let me know if that help, or you have another question.
Hello Dear Developers,
I am working on a project which uses Flickr API, I parsed the data and took the necessary values from JSONArray and JSONObject, however the URL does not provide all the necessary information about the user (the user who shared the photo on Flickr ) for this reason I decided to use flickr.people.getInfo but in this situation, how can I handle response JSON, I mean if I parse this URL, I have to change RecyclerView Adapter, ViewHolder, but it is not sufficient way of handling multiple different API calls.
I hope, the explanation is clear, if it is not pleasing make comment then I will provide answers to your specific questions.
If I understood correctly you should make two calls, then merge responses together and show result into UI.
You can handle this with callbacks or RxJava observables.
The main idea is to create a single class - model that will contain all data you need to present on your UI. Then make the first network call and parse the response into this object. Pass this object to the next network call and update it with the corresponding user data. And only after these two calls are done and you collected all needed data you can insert the model into RecyclerView.
Hope it helps.
I have a JSON query for 3000 items. At first launch my app, I have to retrieve this data and put it in SQLite, in next launches the app will get data from db or will ask api about update data. When app is putting data to db, it should show about twenty items in recyclerview with endless list and load more items, when the items are gonna finished. How implement this? I understand that I need to perform these operations in background threads, but how organize it. At first app will retrieve data from asynchronous retrofit 2 request and how then load this data in SQLite and show it in the same time without lags? Should I use contentprovider with cursorloader or something with ORM? Thanks for answers.
First of All You Should not load this much data at once. you should load that data chunk by chunk (Called Pagination), that mean your calling API also be capable for response to you chunk by chunk.
For your problem you might do is
Load your data from server
Use separate thread or service to handle the data storing into the SQLite.
Use Main Thread to represent the data.
Read this two blogs below, hope this will help you to understand how you can resolve your problem.
RecyclerView Pagination,
Sqlite from Service
I'm working on a movie app, when the user first open the app I would fetch the most current popular movie data and populate it in my ListView. The initial fetch provide a list of movies, but only provide the basic information to fill a ListView (id, name, rating, release data, poster image url). To get the remaining data (run time, tagline, description, movie website, etc), I would have to fetch from /movies/{id} endpoint for each of the movies. Also, for a list of trailer, I would need to fetch from /movies/{id}/videos. Currently I'm fetching the movie detail data when they select the movie on the list using AsyncTask and then setting the Views with the data on the initial detail loading. I'm caching the data in a Content Provider and SQLite.
My questions are:
How do I prefetch the data after getting the initial list of movie
from the first fetch? I'm currently using an AsyncTask for the
initial fetch, do I just start a list of AsyncTask in the middle of
the initial task?
Should I even be using AsyncTask for this situation or are there
better alternatives? It seems like a SyncAdapter is a good idea for
the initial fetch, but not sure what is best to use for the
additional detail/trailer.
I just started working with Android a few weeks ago, so I don't know if I should even be doing things this way or if there are better solutions. Currently everything works, but I'm not sure if I'm going down the right path. I did read this, but wanted a more specific way on how to prefetch data.
This sounds like a good use-case for Volley.
[1] - After you have done the initial fetch you can create your Volley RequestQueue and fire off a bunch of Requests (String/JSON) that you can then parse / cache the result as you already do. Volley is asynchronous, so you do not need to worry about where you add them to the queue, but the callbacks are performed on the UI thread so make sure they are reasonable (they may cause animation jank)
[2] - See above.
I have an Android application which talks to a public Data-API by calling URLs. The API returns XML which describes search results or detailed Data of a particular dataset.
In my Application i retrieve this data and parse it to Java Objects to display them in a ListView for example.
edit: Just to make it clearer: In my Application you can search for music Artists and get their whole discographic information. I Retrieve the list of Releases and display them in a ListView. (No problem right here, because the results of the same search request can change any minute i have to retrieve this data everytime a search request is issued).
Now i have a list with all the LPs the Beatles produced (for example). I can then click one particular LP and view the Details such as the Release Year and the Tracklist.
What i want to cache is the Details data and i'm currently thinking of which is the best way to do this. I thought of:
Retrieving the XML data once and store the XML Data in the SQLite Database (that would imply, that i have to parse the data everytime i want to access it again).
Retrieving the XML data once, parsing it once and somehow store the serialized JavaObject into the SQLite Database as ByteStream. (so all the time consuming work would be done just once).
What do you think is the best version or is there maybe another better way to achieve caching the results?
serializing an object would be quick solution but that could not be effective solution. Every a time you need to load entire object, while in this case if you are storing your data set into database then, using cursor/queries data handling will be smoother.
CursorAdapter will allow you to plug database cursor directly to list in GUI. I would suggest you to use database approach.