IT Knowledge from developers for developers

A person easily gets used to comfort and luxury. In every segment of life. Bigger apartment, better car, new phone, bigger kitchen sink… Those are all good things. But, a person easily forgets how it was before the progress happened. Nervousness in the home, low fuel economy, small screen, lots of dirty dishes…

This reminded me on times before ORM tools. Remember when you had to write a tons of SQL statements, compile them, execute them, read column by column, etc…? Tedious and not very funny to work on. Few of our first Android applications were developed exactly in this manner. We wanted to get used to the platform, get to know it’s APIs and, generally, learn as much as we can about it. This is always a good way to go when you are working with new technologies. But very soon we got tired of going on foot and it was clear that we need some kind of transportation, some vehicle.

Sure, there are ORM tools that can work on Android platform, but, again, we didn’t want third party libraries. We wanted to develop ourselves something which will immediatelly suit our needs. So, we started working on small persistence library that will, hopefully, prove to be no less than excellent.

Activity class is the alpha and the omega of Android development. Almost everything that an Android application does, happens inside of some activity. Activity provides system resources, system services, starts threads, handles UI events,… Because of this, we wanted to make our database easily accessible from every activity that will do any database related operation. At the same time, we wanted to separate persistence and ORM work from any activity class. I believe that many of you involved in Android apps development already had similar situation. So, if you are interested how we tackled the issue, read on and see what we came up with.

As I said, we needed shared and uniform database access across whole application. When it comes to sharing, there are several options that Android provides us. Since we needed only logical sharing, so to say, that is important only while the application is up and running, we decided to go for custom application context. When defining your application in AndroidManifet.xml, you can define attribute “android:name” of your application’s “application” tag. Value of that attribute should be the name of the class which extends android.app.Application and will be instantiated when the app is run. By doing this, we ensured presence of our custom global singleton application context, let us assume that it’s name is “PersistenceApplicationContext”.

In addition to that, we created “database helper” class (extends android.database.sqlite.SQLiteOpenHelper) and wired it up inside of our app’s context. In this early moment, we already have a uniform way to obtain “database helper” class where needed:

From now on, we just had to extend this class and we would have dbHelper ready when we need it. Of course, there is no need to extend this class by every activity. Only those activities that realy work with database should use it.

This approach solves one small problem – shared database access – but how to make it uniform?

In order to make it uniform, we have to have same interface for all kinds of entities we will persist. For that purpose we need “EntityHelper” class:

Looking at signatures of it’s methods, it is obvious why constructor takes Class as one of parameters – by using it, we can determine what is the class of the entity we are reading/storing/deleting and do the ORM job properly. Example of using it (inside of some PersistenceActivity) would be something similar to next fragment of code:

CRUD operations are not the only benefit of personHelper from the example. EntityHelper classes are able to do a bit of object-relational mapping and save us time there to. We decided not to reinvent the wheel nor warm water, so we just used good old JPA annotations: @Entity, @Id and @Transient so far. But, in order to make EntityHelper instances able to do their ORM work, needed entity descriptors have to be prepared.

That information is prepared during the startup of the application. Upon it’s creating, our custom application context triggers the scanning process: persistent classes are scanned, meta data and ORM data is formed and stored in context. At this moment, it gets clear why EntityHelper constructor takes PersistenceApplicationContext as first parameter – by passing it in, we make EntityHelper able to retrieve any data created during the scanning that it needs. Additional feature built on top of all this is SQL generation: based on results of scanning process, SQL statements are generated and can be used when needed since those are also stored in application context.

I admit this sounds very familiar and has resemblance with one famous ORM tool, but I assure you that our idea was not to copy it nor to support many different database systems. We just want and need something that will ease up our work with SQLite on Android devices, make us faster, more efficient and less error prone.

Using this kind of library for really small and simple applications does not make too much sense. But, mobile devices are quickly becoming more and more powerful which will definitely lead to demand of more complicated software. People already need mobile applications fully capable to colaborate with existing (higly complicated) business systems and that is what make developing this kind of library worthwile.

More content about Java

Kommentare

Very useful information, wondering if you were able to successfully use this approach in a reasonablly complex application. Is it possible to post the reference code (application class, dbhelper and base activity).

Hi, Saj, glad that you are interested. We hadn’t opportunity to use this in complex applications so far, but I cannot see why it would make us any problem. Honestly, I would like to see it in serious action as soon as possible – it would give me a chance to see if we made any bad decision designing it. I attached the files you asked for.

Hi Dusan, Thanks a lot for attaching the files, I will definitely give it a try. Right now I’m using a singleton, which stores the global application context when it is first created by any activity and the singleton holds an instance of dbhelper.

You are a brainiac! After looking around for useful information on singletons / DBaccess, I stumbled upon your article. You cover way more than I wished to find, so thanx for pushing open new doors of perception (I only started object-coding some two months ago, and learn more every day). Since I am already p*°# off at all the SQL work that is involved in creating my app, ORM seems like a heaven-sent!! BUT as I am still a noob when it comes to Java programming, I would love to inspect the other code (such as EntityHelper / example Class that needs to be persistent, SQLGenerator). I hope this is not too much too ask for. It would be tremendously helpful and point me into the right direction!

Just wanted to let you know that EntityScanner pointed me to the Java feature of Annotations, which comes in really handy when generating SQL statements etc. Feel like making leaps of knowledge today. Cheers to that and to the one who gave me the hint 😉 PS: I’d still be happy to see the code for the files mentioned earlier!

Hi all, few weeks ago Android persistence library, officially named spa (Small persistence library for Android), was released on GitHub. For more information check out https://github.com/codecentric/spa .