Creating a Service to share database connection between all activities in Android app?
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 th开发者_如何学Pythone 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?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.
You must do a lazy ListView fill, you can declare the DBserviceConn as a private nested into Activity.
public void onServiceConnected(ComponentName className, IBinder binder) {
Log.d(TAG,"DBseviceConn : OnServiceConnected");
this.mBinder = (DBbinder) binder;
//this.mBinder.mDatabaseService.db.queryPlayers(); // No NullPointerException here
mBaseAdapter.notifyDataSetChanged(); //Notify ListView BaseAdapter that data chaged
}
精彩评论