I have to query on 6/7 remote datasets through APIs and then show the results in fragments, I am wondering which solution would be the most performant and better for ux.
Should I create a CursorLoader for each fragment or implement another service which use one response at time to create the fragments and show them?
Related
Question: Assuming I have a web service which returns a JSON which I deserialize into a (list of) POJO(s), should each Fragment get a copy of the datasource or should I keep the datasource only in the activity and let the fragment(s) get the data via a callback interface (which I set in onAttach())? Or is there even another, better way?
WHY
I work with Android for quiet a while now but I think I still have not fully understood some very basic principles and I hope you can help me clarify things. In one of my applications, I use Volley to call a web service which returns JSON formatted data.
I use GSON to deserialize the JSON into POJOs. I then use greenrobots EventBus to send the new data around so I can update the UI. Currently all my fragments are registered as subscribers and each fragment stores a reference to the data.
I think I am doing this wrong because what if a fragment is currently not being displayed (they unregister from EventBus in onStop()). They could miss an update of the model and when a Backstack is popped, they could display an outdated model, right?
So what would be the best way to store the model so that all my UI components and controllers always display the latest version of the model? I'm fearing that one or the other component (Fragment and/or Activity) might miss an update and then displays outdated data.
What is Androids way to store models retrieved from web services and make them accessible for activities and fragments?
I think my main problem is that I can refresh the data in multiple activities and fragments. For example I could reload the data after a pull-to-refresh of a list of entries but renaming an entry would also cause an update - but only of this particular entry.
Have you thought about using sqlite to store the data and then displaying it?
What I would do is as follows:
Fetch data from service as a json
Parse the json and store it in a sqlite table
Read from the sqlite table as and when required
The advantage in doing so is that you are able to store new data as well as update the old one and as you said you can use pull down to refresh functionality, this proves helpful to store the latest data as well as the old one and always display the latest data as you are fetching from a datasource that is being updated.
I have an sqlite db with data I want to load async to a ListView.
I know that Loaders enable easy async data fetching + getting notified on data changed, but from what I see, Loaders work with ContentProviders.
Since in the documentation, it says that
A content provider is only required if you need to share data between multiple applications
I find it weird that using Loaders require a ContentProvider.
I found this thread where it says in one of the answer's comments that
... taking this I just feel I should implement a content provider even so it seems like a overkill for any small database i might want to list on the display ...
Is this the recommended course on action? Is there an alternative?
CursorLoader is designed to work with a content provider, but you can implement your custom Loader to work directly with the database, without implementing a content provider.
take a look -->
Android Custom Loader to Load Data Directly from SQLite Database
I'm new to Android and have successfully implemented an ArrayAdapter to display a list of simple objects in a ListView. I have also created a class that extends SQLiteOpenHelper and I'd like to use this to display a list of rows from the database in the ListView.
From what I can tell, it seems like I should be using a Loader to asynchronously query the data, and act as a middle man between my data and the UI.
The Loader and CursorLoader documentation only refers to how to achieve this when querying a ContentProvider. This led me to think that the best approach may be to create a ContentProvider which provides a structured interface to my database - but the Android documentation on creating a ContentProvider states:
You don't need a provider to use an SQLite database if the use is
entirely within your own application.
Are there any particular reasons why I shouldn't write a ContentProvider? Unless I'm missing something it seems like this would provide a good abstraction for the data layer and mean I can have all the benefits of using a CursorLoader when consuming it.
In my case the database is only for use by my application - so what alternatives are there and are there any good tutorials which show the process start to finish?
Thanks!
I'm having a hard time to optimize backwards compatibility, complexity and best practice for SQLite database handling on Android. I found two not deprecated ways to manage SQLite databases and cursors:
Directly through android.database.sqlite
ContentProvider, CursorLoader and LoaderManager
I'm trying to design the database implementation future proof. This means I would like to implement a best practice promoted by Google. I found a tutorial on implementing ContentProvider and LoaderManager.
If I follow Lars Vogels proposals, my code is blown up with duplications and unnecessary complexity. It does make sense for some tables in my database. But it would make no sense to implement this for a mapping table with three fields (for example). Furthermore I'm having problems with ActionbarSherlock and the Callback Interface of LoaderManager (there's a solution but it would double my data handling classes).
Direct handling of database and cursors via android.database.sqlite is provoking problems with resource management (close your cursors!) and makes me responsible for task handling.
My Questions:
How are you handling SQLite databases on Android?
When do you go the extra mile and implement ContentProvider and LoaderManager?
How do you stay backwards compatible?
My current approach:
I created a class that separates database I/O (via android.database.sqlite) from activities. All methods open and close the cursors they use during their execution (outside of my activities) and return the objects or the data as needed (instead of a cursor). I/O operations are performed in AsyncTasks. This approach seems very deprecated.
I recently had the same plain sqllite / content provider dilemma, and it looks like content provider are the most common approach to solve the problem.
Even if the official doc states that
You don't need to develop your own provider if you don't intend to share your data with other applications
they added the option to have unexported content providers using
android:exported="false"
All the books I read, including Reto Meier's Professional Android Development 4, suggest using content providers.
Moreover, at the cost of a lot of boilerplate code, you can forget about multithreading and open cursor issues.
Anyway, I have to say that the biggest advantage you get from the content provider / cursor loader combo is that your loader is automatically notified whenever the underlying data changes.
If you use plain sqllite you need to implement some way to get the client classes notified whenever the data changes in background. For example, I used broadcasts to notify any activity that the tables where updated inside an intentservice.
Finally, I was a bit disappointed by all the code duplication that you are ranting about, and I decided to write a python script to generate the content provider in my place using just a description of the data model. You probably have to modify the generated class (or better, to extend it), but I think it saves quite a lot of time. You can find it here
Conclusion:
if you want to export your data to other apps (not so common), you need to go for content provider
if you want to observe the data / update the ui because your dataset might be changed in background, content provider + loader is extremely powerful
if you have a preloaded data set, and maybe you update it in the same activity that display the data, or you need to perform simple operations with your tables, maybe a sqllite helper class is just enough
I am trying to understand that what is loaders. Can anyone share an example with it? I don't know when we can use multiple loaders in an activity or fragment. I can't figure out one instance of multiple loaders to implement.
Loaders, while commonly used to populate lists, can be used for a whole host of things. Basically, anything you to do on a separate thread can be done in a loader. If you need to make multiple calls to the network and need to do different things when you get the results, that's when you'd use multiple loaders. You could also use one loader to populate a list with a cursor, and another loader to do network calls.
I don't know when we can use multiple loaders in an activity or
fragment. I can't figure out one instance of multiple loaders to
implement.
Here you go!
Let's suppose you are making a news app.
You have a ListView/RecyclerView on your Launcher Activity which displays the news. Each of your listItem has one ImageView to display thumbnail, two TextViews - one for news article title & another for news article category(Ex: Politics, Sports, Technology).
Now, in order to get news, you have to fetch data from a remote server(website) using their API. And when you fetch data, that website returns data in the form of JSON.
You have to connect to that website, get the JSON, parse that JSON (i.e. extract news article title, news article category, thumbnail_URL). Then you have to download thumbnails from extracted thumbnail_URL and bind data to your ListView/RecyclerView.
In this case, you could use one Loader for parsing JSON; use another Loader to download thumbnails from extracted thumbnail_URL.