views:

852

answers:

3

I have a todo list type application that stores all of the note data in a sqlite3 database. Each activity in the application needs access to the database to edit different parts of the data in real time.

Currently, I have each activity open its own DBManager object (the helper class I created to manage the database). This is causing problems though and I would like a slightly more global access solution so I don't have to keep opening/closing/creating a database.

I'm considering several options, and would like to hear pros and cons of each as well as other suggestions.

  1. Singleton style. Have a wrapper class that returns a reference to the only database manager so any activity that needs it can use it.

  2. Static Manager. Have the manager class be entirely static members and have it open the database on load. Easily accessible by anyone that needs it (which is everyone).

  3. Merger between 1 and 2. I could make a database manager class that initializes the member singleton instance of the database and all of the data manipulation methods were static. Then I wouldn't even need a reference to the singleton to access the database. I like this solution best, please point out downsides.

Suggestions?

A: 

The recommended way to do this on Android is to use a ContentProvider. Your first content provider may feel like more trouble than it's worth, but once you get the pattern down it shouldn't be too bad provided you aren't trying to serialize blobs.

Mike
Details on content providers here: http://developer.android.com/guide/topics/providers/content-providers.html Also see the NotePad sample bundled with the SDK for an idea of how to use them.
Roman Nurik
Content providers are for cross-process data sharing. Using them as a layer inside a single application decreases performance and decreases flexibility (e.g., no joins).
CommonsWare
I just need to access the data inside my own app and a Database suites my needs best. I just want to be able to access it more easily than opening a new helper class in every single activity and control view that needs to persist data.
CodeFusionMobile
+2  A: 

This is causing problems though

Which are...what?

and I would like a slightly more global access solution so I don't have to keep opening/closing/creating a database.

Opening and closing a SQLite database is cheap. Statics and singletons are to be avoided wherever possible. What makes you think your current solution is bad?

CommonsWare
I may have to access the database from every view in a custom list at some point and I wanted to know if there was an option for that. Creating a new manager object for each view would be expensive. That's what's causing problems.
CodeFusionMobile
"Creating a new manager object for each view would be expensive." Then don't create new managers for every view. That's not how Android works. 1. Run a query(), get a Cursor. 2. Wrap the Cursor in a custom subclass of SimpleCursorAdapter. 3. Override bindView() in the SimpleCursorAdapter to get data out of the Cursor position and pour it into the row. 4. Override newView() to create an instance of the row View in question. 5. Hand your custom adapter to your ListView.
CommonsWare
I decided to create my own custom listview because I needed to handle click events from button controls on the content views and the standard listview causes problems with that by design. I do the cursor binding myself and generate the list. The reason I would access the database from the views is because I need to update a field based on click events internal to the view. If I had global access to the database, I wouldn't need to reflect those events to the custom list and it would make other parts of the app simpler as well.
CodeFusionMobile
"The reason I would access the database from the views is because I need to update a field based on click events internal to the view." If your View is an inner class of your activity, you already have database access. If your View is not an inner class of your activity, that can be adjusted in 10-15 seconds, I would imagine.
CommonsWare
I never thought of making the view class internal. I like it. +1 for that.
CodeFusionMobile
Just an update for your benefit. The suggestion of making the view class an inner class of the activity allowed me to solve several issues with my application. That, combined with another post on making children non-focusable, allowed me to implement my activity as a standard list activity. Your post did not answer my specific question, so gregm still gets the checkmark, but you solved my underlying issue, thanks.
CodeFusionMobile
Yeah, inner classes work fairly nicely in various places in Android. A highly recommended technique. Glad it is working for you!
CommonsWare
+3  A: 

In my opinion, the Content Provider is complicated and if you are not sharing with activities that are not your own, you don't need it. Therefore, I suggest you use a singleton class first. Then if you have more time or need it, go for the Content Provider.

I've used a singleton successfully for 6 months without much difficulty. (I was careful to really make it a singleton though, only one instance that loads the data once)

Singleton

  • Advantage: Easy to implement
  • Advantage: because I used a common instance, I could implement caching easily and hence make the application not have to do to the database as often
  • Disadvantage:can't share your data with external Activities

Content Provider

  • Advantage: You can share your data with external Activities
  • Advantage: You can integrate with the Search API
  • Disadvantage: Complicated, need to represent your data in a different way
  • Disadvantage: Yet another Android API to spend time learning
gregm
Never considered content providers at all because I liked the database, familiar with sql, and didn't need to share data with outside apps. What about singleton versus static? Could I make a database manager class that created its own singleton and all of the access methods were static? Then I wouldn't even need a reference to the singleton?
CodeFusionMobile