Android. Content provider or Database? - android

I'm a bit confused in the question, if it's better to use ContentProvider or Database. Or it makes no difference if I don't want to share any data with other applications.
If I've understood it right, content providers based on SQLite DBs and it's also possible that content of them is only accessable for my application.
Can you give some explanations?
Thank you very much,
Mur

There certainly are worthwhile problems for which a provider is a solution, particularly for cross-app data publishing. For example, you need to use a content provider to supply search suggestions to a Quick Search Box.
However, for internal use within an application, I am not a fan. The benefits IMHO are outweighed by the costs (e.g., reduced flexibility, additional overhead).
If you do implement a content provider, bear in mind that they are accessible by other applications by default. You need to include android:exported="false" in the <provider> element to make them private to your app.

Using a content provider will give you a more modular design, and make your life easier if you at some point in future would like to reach the data from other applications.
If you are certain that the data will only ever be needed from one application, you might as well operate directly on the database.
There is one particular SQLite limitation you should be aware of and that is that SQLite is single-user only. What this really means is that you will need to guard your database from being accessed from multiple threads at the same time. This is generally not a problem in a content provider, since they almost always have a single-threaded implementation.

Reasons to use content provider are here.
In summary:
Easily change the underlying data source (you can change your db from Sqlite to Mongo or to a JSON file without any app changes)
Leverage functionality of some Android Classes (SyncAdapter, Loaders, CursorAdapter) - These classes require content provider and you cant use them if you dont have one
Allow many apps to access, use and modify a single data securely. (which is really the main reason for using it)

Related

The most efficient way to implement a database using custom data + google fitness api

I am currently learning android programming and creating an app that will store some integers representing user choices (values inserted several times a day, must be displayed in the results activity) and steps data collected Google Fit HISTORY Android APIs, also displayed in the results activity. I am looking for the most efficient way to store this data. I know that it might be possible to insert the custom data types in the GOOGLE fit database. However, I am not sure if it is a good idea if the app mostly works offline, and it needs to immediately represent only a small set of results, for example, the values inserted in the last 2 weeks, with step counts. On the other hand, I am not sure if it is ok to have two databases storing the data.
My apologies if the question sounds a bit too amateur, I am doing my best to find an optimal solution in terms of performance.
Thank you for your answers.
So, to give you my opinion and answer (mainly opinion)
Android has 3 ways (mainly) for storing data:
Files
Online database/API
Local database
for this specific scenario you have listed, wanting the data to be available offline, you should probably be looking at using Room: https://developer.android.com/training/data-storage/room, as it supports storing primitive types without having to write any type converters, you can store models and custom data as well, it uses very basic SQL (because it's a wrapper for the older Sqlite database methods) and is part of android (not an external 3rd party library). Room also requires most operations to be done off of threads, instead of main threads and this will improve your performance as well (also has support for livedata/rxjava to observe straight onto any changes as they happen)
However, as I told this user here:
Should i store one arrayList per file or should i store all my arrayList in the same file?
When starting out, don't worry about the best way for doing something, instead, try something out and learn from it, worrying about the best solution now is rather pointless, either way, happy learning and coding :P

Large String Object in SQLite Database

I have a SQLite database which has a table (of course) named Object. In my application, I need to access that table and all of its fields. I am able to query the database and get all of the information I want from a cursor with no issues. The problem comes with deciding what to do with the cursor next. Right now I am thinking of creating a class called Object and it will have fields for every column in the table which will be set by the query. This just seems so... inefficient. I'm not sure how to do this without needing to write out every column that is in the table for the object to use, which seems to violate DRY. Are there any better ways to do this?
My end goal is to be able to access every row in the table and get whatever information I want for that row. For example I will be using this to populate a ListView. If this is too ambiguous let me know and I'll try to clarify.
Thanks!
Edit: I've found the library db40 and it seems to do what I want. The library seems to be kind of big though (40 mb) for a mobile application. Does anybody have experience with this? Everything I've read seems to indicate it is good. I'll post more if I find information.
Are there any better ways to do this?
This is very "wide" question and depends on personal requirements and what is for developer more comfortable. I'm using your idea that is for me the best one you can use.
Generally we can say you want to create ORM (object-relation mapping). It's very clean and efficient approach (my opinion). Of course sometimes is not the best solution to use ORM ( i never met with this case but heard about it). I almost always use my own defined ORM for sure it takes some time but results are significant against done frameworks.
Both have advantages and disadvantages. Own ORM has much more higher performance because it's designated and optimized for concrete solution (mainly queries etc.).
I suggest you to do what you mentioned -> create object that will represent table in database with properties equal to columns. I'm using this in work and we never had problems with performance or too much battery consumption with our applications.
It's also much more safe if you'll show user some data not directly from database but "copies" in objects. Users can do whatever want with dislayed results (they can add some dangerous symbols and hacks) but now you can easily check this before you'll want to update database(s) with changes.
Your source-code looks good, another developer won't be lost in your code, everything will be clear and easy to do updates for future.
I provided you "my opinion" on this thing so hope it'll help you with make a decision.

what are the advantages of using a ContentProvider over normal SQLIte storage?

I want to share data across multiple applications, instead of having a ContentResolver->ContentProvider mechanism, I can just define a client library which talks to the process which does the SQLite DB operations right?
What does the ContentProvider brings in here which we cannot achieve by having a Process expose the data?
You can find answer Exact Difference between “Content-Provider” and “SQLite Database”.
But I like to explain this..
What does the ContentProvider brings in here which we cannot achieve by have a Process expose the data?
There is one particular SQLite limitation you should be aware of and that is that SQLite is single-user only. What this really means is that you will need to guard your database from being accessed from multiple threads at the same time. This is generally not a problem in a content provider, since they almost always have a single-threaded implementation.
Also It's good practice to provide the extra level of abstraction over your data to make it easier to change internally. What if you decide to change the underlying database structure at a later time? If you use a ContentProvider you can contain all the structural changes within it, where as if you don't use one, you are forced to change all areas of the code that are affected by the structural changes. Besides, it's nice to be able to re-use the same standard API for accessing data rather than littering your code with low-level access to the database.
You can check the thread below:
Exact Difference between "Content-Provider" and "SQLite Database"

Content Provider vs Direct Database Access (Transaction Management)

I understand, at least on paper, the basic difference between the Content Provider and just directly accessing the SQLiteDatabase. I have a functioning prototype for my application, and currently it is just directly hitting the database. I don't really have any experience using the Content Provider pattern, but I have found out that I will need to share some data with another application.
I will only be sharing about 2 out of a dozen or so tables, so I was wondering if I should be just completely redoing the data layer to follow the Content Provider pattern, or just expose only those tables via a Content Provider for the sake of the other application and still directly access the database in the primary application.
One of the issues I ran into with my prototype was that I have some fairly complex transactions, and the code I wrote to get that working is not designed particularly well and isn't reusable at all. As I add more functionality to this app, I'm going to need a better designed data access layer, before I set off writing my own, does anyone know of any good resources with design patterns for this type of thing already? Also, if I need to go the Content Provider route, am I going to have solid control over the database transactions?
I don't think you should have a problem just making a content provider with the functionality you need that sits on top of your direct database code. A content provider is really just an abstraction for accessing structured data that happens to look very much like SQLite. :) If various internal parts of the app directly access the same database as the provider, as long as the code of the two plays together nicely, it should be fine.
I actually am not a fan of being absolute about "thou must always use content providers." If you don't need a content provider, don't use one; just do direct SQLite if it is easier. If you need a content provider for some specific interaction with other apps, feel free to write one just for that without making it a big complicated thing that supports all of the stuff your app does internally with the database. If this is easier, great. It also makes it much less likely for you unintentionally to expose private data from your app to others.
Don't quote me on this, but I'm pretty sure a content provider is a way to abstract the way you are providing data to an object. This way, your object can just communicate with the provider, and doesn't care about the implementation i.e. how/where the data is stored. Perhaps you might want to provide some other way to store your data in the future, and using the content provider paradigm will save you tons of rework, since it's just interface based communication.
I would use the Android design patterns everywhere I could. To be honest, looking at it now I really should be doing this in my project.

Possible to write custom content provider for existing system database?

Not sure of the absolute utility of this but seems as though it should be possible and useful.
Can you extend ContentProvider to provide URIs representing new queries (i.e., joins across multiple tables not specified by existing URIs) for an existing system database?
The alternative seems to be that I need to write a series of cursor queries then join them -- seems like a lot of unnecessary code duplication.
I have been trying this for the contacts database as an exercise, but no love so far.
The crux seems to be that I cannot open a database in another package during the setup phase.
Am I just completely out in left field here?
It's possible as I am new to both Java and Android.
Comments and/or pointers to relevant resources are appreciated.
Thanks,
Steve
Can you extend ContentProvider to
provide URIs representing new queries
(i.e., joins across multiple tables
not specified by existing URIs) for an
existing system database?
Not really, only because you don't have direct access to existing system databases, in terms of SQLite. Now, creating a ContentProvider that performs your joins for you, as a reusability measure, is certainly doable, though I would get worried about the performance overhead of multiple cross-process hops.

Categories

Resources