tags:

views:

182

answers:

1

I've been trying to figure out the best way to handle local database access in my android applications. I had been creating a database connection object in each activity but this seems like a really inefficient way to do things. Doing some research I stumbled onto this discussion. Using a Service seems like a great way to do things, but I am having trouble getting it working. Here is what I have:

SERVICE:

public class DBservice extends Service {
    private final static String TAG = "net.iamcorbin.frolfcard";
    public DBconn db;

    private DBbinder mDatabaseBinder = new DBbinder();

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG,"DBservice : onCreate");
        mDatabaseBinder.mDatabaseService = this;
        this.db = new DBconn(getApplicationContext());
        this.db.open();
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG,"DBservice : onBind");
        return mDatabaseBinder;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startID) {
        Log.d(TAG,"DBservice : onStartCommand");
        return Service.START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG,"DBservice : onDestroy");
        mDatabaseBinder.mDatabaseService = null;
        this.db.close();
    }
}

BINDER:

public class DBbinder extends Binder {

    public DBservice mDatabaseService;

    public DBconn getDB() {
        return mDatabaseService.db;
    }
}

SERVICE CONNECTION:

public class DBserviceConn implements ServiceConnection {
    private final static String TAG = "net.iamcorbin.frolfcard";

    DBbinder mBinder;

    public DBserviceConn(DBbinder binder) {
        Log.d(TAG,"DBseviceConn : Constructor");
        this.mBinder = binder;
    }

    public void onServiceConnected(ComponentName className, IBinder binder) {
        Log.d(TAG,"DBseviceConn : OnServiceConnected");
        this.mBinder = (DBbinder) binder;
    }

    public void onServiceDisconnected(ComponentName arg0) {
        Log.d(TAG,"DBseviceConn : OnServiceDisconnected");
    }

}

ACCESSING:

private DBbinder dbBinder;
private DBserviceConn dbServiceConn;

//In onCreate() for Activity that wants to access database
//Setup DB Service Connection and Binder
this.dbServiceConn = new DBserviceConn(this.dbBinder);
final Intent i_DBservice = new Intent(PickGame.this, DBservice.class);
//bind DB Service
this.bindService(i_DBservice, this.dbServiceConn, BIND_AUTO_CREATE);

This executes without throwing any errors but when I try and use the database with:

this.dbServiceConn.mBinder.mDatabaseService.db.queryPlayers();

it throws a NullPointerException. From reading the discussion(linked above) I'm assuming that this is because the database just isn't open yet because I'm doing the query in onCreate immediately after bindService. I need to use the database to populate a ListView though.

So the question is
1. Am I creating the service, binder, and service connection properly?
2. If so, how do I go about creating the callback to populate the ListView once the Service is started, bound, and the database opened?

+2  A: 

Wow, that's a lot easier. I removed the service and just handle the database connection in the application object.

APPLICATION:

public class App extends Application {
    public DBconn db;

    @Override
    public void onCreate() {
        super.onCreate();

        this.db = new DBconn(getApplicationContext());
        this.db.open();
    }

    @Override
    public void onTerminate() {
        this.db.close();
        super.onTerminate();
    }
}

ACCESS:

this.app = ((App)getApplicationContext());

this.lv_players_c = this.app.db.queryPlayers();

Thanks Pentium10. I would still like to know if this is the most efficient way to handle the connection though. Is it fine to leave the database connection open for the duration of the Application lifecycle? Or would it be better to open and close the database whenever I need to use it in an Activity?

Any other suggestions or confirmation of using this method would be great.

Corbin Tarrant
The official docs state that you can't rely on your application being shut down correct. This means that all writing should be done in the onPause method as the latest point in you lifecycle. There are no other problems I can think of with having an open connection the the database all the time.
Janusz
I went with the same solution and it seems to be working great.
taer