How to prevent multiple databases from being created within Android app? - java

I'm relatively new to Android programming and I have little to no experience with SQL and its interaction with Java altogether, but I couldn't find the answer I was looking for either in tutorials or Google's developer pages.
I'm wondering how I can create a database in Android to store a variety of String and int variables without creating duplicate databases. I understand the schema and contract class concept presented by the development page, but I don't understand how I am supposed to call a class method so that only a single database is created (preferably at first app launch) without several instances being created.
My main question: What sort of setup is recommended to create a database that can be referenced from other classes, exists from the very first launch of the app, and remains private (although to be honest it's not a huge priority)?

but I don't understand how I am supposed to call a class method so
that only a single database is created (preferably at first app
launch)
In Android, database is created only once and then whenever you will try to perform CRUD operations and selects statements, always you will have only one database created. It's same for table(s) in database. Once table(s) are created, they won't be created again (so be careful if you'll add new columns to table during implementation if table was created before without new columns1). Moreover if user explicitly will delete application data - only in this case, database and table(s) will be created again because they were deleted.
What sort of setup is recommended to create a database that can be
referenced from other classes, exists from the very first launch of
the app
In the moment when you'll call for example getWriteableDatabase() or getReadableDatabase() database and table(s) will be created - only at this time! Only once. No more (except1. After that, whenever you'll try to attempt to read or write from / to database your database will be opened with specific permissions (read-write or read-only - it depends how which method you called) and you can perform actions.
without several instances being created.
Database is only one - it's not duplicated (physically), absolutely but when application logic is not designated correctly, there may appear multiple instances of database and this fact is not very good and usually a nightmare of many beginners with Android and SQLite.
But solution exists and it's not hard to implement -> Singleton. Design pattern Singleton is "pretty cool tool" for our goal - ensure that only one instance of database will be ever created.
Here is implementation of Singleton itself:
public class DataSource extends SQLiteOpenHelper {
private static DataSource instance;
public static final DataSource getInstance(Context c) {
if (instance == null) {
instance = new DataSource(c);
}
return instance;
}
}
1 If you added new columns to table at the time when database and table were created before (how i mentioned above the're created only once) it may cause application exception so exactly here you have to clear application data or implement onUpgrade() method.

Try using an ORM like ActiveAndroid. While not recommended for extremely complex apps, using an ORM will make using and managing a database much easier for someone without much database experience (and can make your code more readable as well).

When I did my first SQLite DB in Android, I used this site to get me trough the basics.
To answer your question, take a look at the DatabaseHelper Class. You will see that you have to specify a DB name (filename).
private static final String DATABASE_NAME = "commments.db";
Android will automatically create the DB if it's not existent (newly installed app) and will reuse it if it's there. As long as you use always the same file (and don't mess up the tables), your DB will remain intact.
Also, for security, the DB is stored in the app's data. Not accessible with a file browser (unless you are rooted). You can download the DB via adb if you really need to. There is tons of documentation on how to gets apps private data.
Hope this helps!

Related

Is using one class to store data safe?

So I was searching about storing data in one class, and found this. However, that's not what I'm looking for. What I wanted to know about this was whether it's bad practice, can cause performance issues in an application, or if there's another way to do it, etc... (and I'm not doing this on an Android).
Let's say I have a class that stores a HashMap<Enum, Object> and is initialized when I create the class in main.
public Main() {
// Creates the HashMap, initialized in the constructor 'MemoryContainer'
MemoryContainer m = new MemoryContainer();
m.getTestHash().put(SomeEnum.TEST, "Test"); // Using created HashMap
}
Other than casting the value every time I use it, would this cause major issues? If so, is there an alternative?
There's nothing wrong with storing static values in a class, however this is not a good practice.
To store the constants you should create an interface as every field in an interface is already a constant (public static final).
A better approach will be to store these values in properties files, and load them as needed.
A properties file can be stored externally and a person who isn't aware of your source code would be able to modify this properties file if needed. For example you can store database connection details in properties files and if server support admin determines that database instance is down, he/she can edit the properties file to point the application to a new one.
Finally for most flexibility you shouldn't store the configuration inside application at all. It can be stored in a database like MySql or in a fast data structure storage like Redis. This will allow multiple instances of your application to share the configuration data and it will also allow you to modify configuration on the fly by modifying them in the database.
Sometimes a Git repository is also used to store this kind of data (like in case of microservices). Git repository in addition to being shared among all the instances, also maintains the history of modifications.
I would not look too much at performance issues (of course, I do not know what else your application does or wants to do and how it achieves it).
What you should look at first is Mutability - in your example, nothing would stop me from changing the configuration at Runtime by calling
m.getTestHash().put(SomeEnum.TEST, "NotATestAnymore") - this would immediately change the behaviour for every other use of that specific setting.
I am also not sure why you would not just use a configuration class that would directly provide (typed) getters and, if you know all configuration settings at the launch of the app, one constructor containing all the settings.
Do you plan to read the configuration from an outside source (e.g. file)?
NO,
It won't cause major issues.
Also, it is a good practice to keep those variables (HashMap in your case) in a different class away from your main class (which contains your app logic).

Should I turn my SQLite class into a singleton?

I'm in the middle of creating an Android application with multiple tables inside of my database. The database is going to be constantly accessed, but with that said I've stumbled upon the idea of a singleton from http://www.javaworld.com/javaworld/jw-04-2003/jw-0425-designpatterns.html
Would it be advised to try to make a database a singleton so that I never have conflicts?
EDIT: In response to the first comment. I have an SQLiteOpenHelper class that I believe I can structure into a singleton.
It depends on your application and design. You can make a class singleton if it only creates a database.
But if you make singleton a class which executes query, you have to make sure that it doesn't gets called while the first query is executing. So a locking mechanism or queuing will be required then.

Thermostat to DB, OOP Design

I am attempting my first Java project (just started learning it/OOP). I have built a thermostat circuit that I can get the temperature from using a driver, and am now in the process of designing a Java program that interfaces with the thermostat and inserts the data into a mysql DB.
I'm attempting to do this properly, and so have come up with a basic UML diagram of my classes/objects and how they interact.
I plan on using a database interface class which will extend a database connection class. This database interface will insert into the DB, and the database connection constructor will create the database connection.
I will also have a thermostat class which interfaces with the thermostat itself, it will have 2 private variables, temperature and humidity. It will have the method update temp, which will update the private variables. The get temp method will be provide the interface to these private variables.
Finally the control class is composed of the thermostat and database interface classes, and will call the methods of both classes to get the temp/humidity data into the database.
UML diagram:
Do you have any thoughts? I don't know how good this design is. Is the controller interacting with the other classes in the correct way?
Thank you for your time.
X.
First, for someone that just "just started learning it/OOP" it look pretty good!
One thing that jumps out as me: It works, but seems idiomatically wrong (we don't usually do it that way) is having your DAO (data access object, "Database Interface") extend the class that creates the connection. Instead is should use this class-- or better, the result of this class, a connection.
Why? As you write more DAO classes (in this project, or others) you'll probably find that these are two separate concerns:
(1) code that deals with the temp/humidity table and related SQL and, temperature specific logic and exceptions.
(2) code that is responsible for connecting to a database and creating connection objects.
If you have a databaseInterface.setConnection(Connection c) method, you'll find that your databaseInterface class is more reusable. You can set connections from various sources, create multiple instances with different connections, inject mock connections in your test cases, etc.
These are ideas that I have learned over years and usually apply to projects with tens to hundreds of data access classes. Its not a terribly significant in a small project, but is a possible improvement nonetheless.
EDIT: Possible Controller constructor:
// My hardware interface
private Thermostat thermostat;
// My temperature DB tables interface
private TemperatureDAO temperatureDAO;
public Controller() {
thermostat = new Thermostat();
temperatureDAO = new TemperatureDAO();
// As the controller, I get to decide what connection the application uses.
temperatureDAO.setConnection(new ConnectionProvider().getConnection());
}
In this code the controller is dictating which DB connection is used, not each individual DAO.

Android database best practice

Coming from a perl background and having done some simple OO in that, I am struggling to grasp the android/Java way of interacting with databases.
In my experience I would create a file or class for each object, and an object would match/represent a table in the database.
Within that object would be a constructor, variables for the data, methods/functions to return individual variables but also the DB queries to read and write from the DB, doing all the necessary CRUD functions.
From what I read on the web, in Android I would create the objects similarly but without the DB interaction. This would happen in either a single class with all my DB functionality in it, or multiple DB classes, one per table.
My questions are all to do with best practices really.
Can I do my app how I would in Perl. If not why not, and if so,what are the pros and cons and limitations?
What do the terms DAO, Adapter and POJO mean?
Should I make an application class and globally declare the DB there?
Should I create one handler in each activity or in the application class only?
I have read so many tutorials now my head is spinning, all with a diff way of doing things and mostly only with a single table and few showing actual objects directly representing tables.
I'm happy to hear opinion, be linked to tutorials or just have the odd term explained.
Thanks in advance
If I am reading you correctly, ORMLite may be your best bet. It uses reflection for database creation and maintenance which seems to be how Perl does it.
POJO is Plain old java object which means it is just a normal class.
An adapter would be the class that contains the CRUD stuff and manages the database itself. There are quite some patterns around in the Android world and talking about can fill a book.
I prefer the pattern, that I open the database once in my Application class and I never close it (Android does that when it kills the app). A sample from a very old project I had might show you the basic idea.
DAO is Data Access Object and can fill dozens of books. If would just start programming and see where you're heading...
The other poster is correct in putting out ORMLite as a great way to manage code relationships that mirror your database. If you're looking to do it on your own, however, there are a ton of ways to do things, and I wouldn't say the community has really gravitated toward one over the other. Personally, I tend to have my entities represented by Plain Old Java Objects (POJO - implies no special connectivity to other things, like databases), where the various attributes of the table correspond to field values. I then persist and retrieve those objects through a Data Access Object (DAO). The DAO's all have access to a shared, open, Database object - against which they execute queries according to need.
For example: if I had a table foo, I would have a corresponding entity class Foo, with attributes corresponding to columns. class FooDAO would have mechanisms to get a Foo:
public Foo getFooById(Integer id) {
String[] selection = {id.toString()};
String limit = "1"
Cursor c = mDatabase.query(FOO_TABLE, null, "id=?", selection, null, null, null, 1);
// Create a new Foo from returned cursor and close it
}
A second entity bar might have many foo. For that, we would, in Bar, reference the FooDAO to get all of bar's member foo:
public class Bar {
public List<Foo> getFoo() {
return mFooDAO.getFooByBar(this);
}
}
etc... the scope of what one can do in rolling your own ORM like this is pretty vast, so do as much or as little as you need. Or just use ORMLite and skip the whole thing :)
Also, the android engineers frown on subclassing Application for globally accessible objects in favor of Singletons (see hackbod's answer), but opinions vary

Background methods always as private class?

I'm starting with Android and wonder if background Task like DB reading and saving are always encapsulated in private classes?
I mean, at the moment I have:
private class SaveToDB extends AsyncTask..
private class ReadFromDB extends AsyncTask..
public void onButtonClick(View v) {
new SaveToDB().execute();
}
And so on. This way, I always have to create a new object if I want to execute background tasks. Is that the correct way?
What I wonder is that all my private classes are "actions" itself, not really objects. As they are named eg save or read which naming normally applies to methods by convention, not to classes.
Moreover, in case I'm doing it right: is it good practice to neast the private classes inside MyApplication Activity? Or should I refacter them out into own separate classes?
You could write a service to handle all the background content management. So, when you want to save, you just message the service and tell it to write data. This is much more complicated. For simple things, you can do it exactly as you are currently.
EDIT:
Also, as Ian pointed out, take a look at the new database interfacing classes post 3.0.
If you are firing of async tasks to interact with a sqlite database, then its not the best way to do things these days, you should check out cursor loaders instead.
http://developer.android.com/guide/topics/fundamentals/loaders.html
http://developer.android.com/reference/android/content/CursorLoader.html
Once you got your head around them they are much easier than firing off async tasks, infact they build on top of async tasks to address some of the issues you describe and are tolerant to configuration changes.
I highly recommend to move away from AsyncTask (for db access) and use the Loader API instead.
Its backported in the compatibility package so you can use them in older versions prior to Honeycomb.
Not always.
For example, if you've got a task that is to be used by different activities (I'm not talking about sharing the same instance), you will want a public class so you don't write it several times.
If you only use that (class of) task in one place, private class might help keeping your code cleaner.
It is a correct way for using AsyncTask, which isntance you can execute once.
Class Name can be DbSaver isntead of SaveToDb for instance which is more readable.
If that class is used only one Activity you can nest them, why not. But if you have task which is executed within different Activities, it is a good idea to create his own file.
It is good design to loosely couple your database access from your UI code. One way to avoid having to create a new object every time would be to make the database access classes a singleton and just return the instance of the class whenever you need to make a transaction.
To your last question it is a better idea to move the database management to its own class so that it can be accessed across several activities. If you do it all in a private class then what happens when you have a new activity that need s database access?

Categories

Resources