I'm developing an android 3.1 application.
This question is not specific for Android, it is about how to design a class that access a database. I asked here because my code is for Android.
I have a class, DBManager, to work with Sqlite database. This is a part of its implementation:
public class DBManager
{
// Variable to hold the database instance
private SQLiteDatabase db;
// Database open/upgrade helper
private DatabaseHelper dbHelper;
public DBManager(Context _context)
{
Log.v("DBManager", "constructor");
dbHelper = new DatabaseHelper(_context, SqlConstants.DATABASE_NAME, null, SqlConstants.DATABASE_VERSION);
}
public DBManager open() throws SQLException
{
Log.v("DBManager", "open");
db = dbHelper.getWritableDatabase();
return this;
}
public void close()
{
Log.v("DBManager", "close");
db.close();
}
...
/**
* Query all forms available locally.
* #return A list with all forms (form.name and form.FormId) available on local db
* or null if there was a problem.
*/
public ArrayList<Form> getAllForms()
{
Log.v("DBManager", "getAllForms");
ArrayList<Form> list = null;
Cursor c = null;
try
{
c = this.getAllFormsCursor();
if (c != null)
{
int formNameIndex = c.getColumnIndex(SqlConstants.COLUMN_FORM_NAME);
int formIdIndex = c.getColumnIndex(SqlConstants.COLUMN_FORM_ID);
c.moveToFirst();
if (c.getCount() > 0)
{
list = new ArrayList<Form>(c.getCount());
do
{
Form f = new Form();
f.Name = c.getString(formNameIndex);
f.FormId = c.getString(formIdIndex);
list.add(f);
}
while (c.moveToNext());
}
}
}
catch (Exception e)
{
e.printStackTrace();
list = null;
}
finally
{
if (c != null)
c.close();
}
return list;
}
private Cursor getAllFormsCursor()
{
Log.v("DBManager", "getAllFormsCursor");
return db.query(SqlConstants.TABLE_FORM,
new String[] {
SqlConstants.COLUMN_FORM_ID,
SqlConstants.COLUMN_FORM_NAME}, null, null, null, null, null);
}
}
And this is an AsyncTask that uses DBManager:
private class DbFormListAsyncTask extends AsyncTask<Void, Void, ArrayList<Form>>
{
private Context mContext;
private ProgressDialog loadingDialog;
private DBManager dbMan;
DbFormListAsyncTask(Context context)
{
this.mContext = context;
loadingDialog = new ProgressDialog(mContext);
loadingDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
loadingDialog.setMessage("Retriving forms. Please wait...");
loadingDialog.setCancelable(false);
loadingDialog.show();
}
#Override
protected ArrayList<Form> doInBackground(Void... arg0)
{
dbMan = new DBManager(mContext);
dbMan.open();
return dbMan.getAllForms();
}
protected void onPostExecute(ArrayList<Form> forms)
{
if (forms != null)
{
ListActivity act = (ListActivity) mContext;
act.setListAdapter(new AvaFormAdapter(act, R.layout.ava_list_item, forms));
}
else
{
TextView errorMsg = (TextView)
((FormsListActivity) mContext).findViewById(R.id.formErrorMsg);
errorMsg.setText("Problem getting forms. Please try again later.");
}
loadingDialog.dismiss();
if (dbMan != null)
dbMan.close();
}
}
As you can see I have to:
Create DBManager instance.
Open database with dbMan.open()
Call dbMan.getAllForms()
Close database with dbMan.close() on onPostExecute.
I thought that I could add db.open() and db.close() on dbMan.getAllForms() to avoid calling it every time I use dbMan.getAllForms().
What do you think about this? What is the best approach?
I would put it inside getAllForms() or do something like that
protected ArrayList<Form> doInBackground(Void... arg0)
{
dbMan = new DBManager(mContext);
dbMan.open();
ArrayList<Form> resutl = dbMan.getAllForms();
dbMan.close();
return result;
}
Since you don't need the db connection after you have the result you can close it right away.
Edit: if you run that AsyncTask several times then opening/closing will introduce unnecessary overhead. In that case you may want to instanciate the dbManager from your Activity (maybe open() in the constructor of DbManager) and close it once you leave your activity. Then pass Dbmanager to the AsyncTask.
Make your database helper class a singleton, and don't explicitly close the SQLiteDatabase. It will be closed and flushed when your app's process exits.
Related
This question already has answers here:
Simple export and import of a SQLite database on Android
(5 answers)
Closed 9 years ago.
It is possible to use an already created database sqlite in android? I already created database in sqlite in mozilla ad-ons. How should I use it in my android application? Anyone can help me??
First, to use a database, in general, in android, you should extend the SQLiteOpenHelper class. This class is the one responsible for creating your database (and upgrading) when needed from a sql script you provide in your implementation.
So the trick is, you need to override the behavior of the SQLiteOpenHelper to copy your database file from the assets folder instead of create your database.
in this blog post, i explain in details the process of overriding this behavior. but here is the final code.
use the Repository class as you would use SQLiteOpenHelper normally.
public class Repository extends SQLiteOpenHelper {
private static final int VERSION = 1;
private static final String DATABASE_NAME = "data.sqlite";
private static File DATABASE_FILE;
// This is an indicator if we need to copy the
// database file.
private boolean mInvalidDatabaseFile = false;
private boolean mIsUpgraded = false;
private Context mContext;
/**
* number of users of the database connection.
* */
private int mOpenConnections = 0;
private static Repository mInstance;
synchronized static public Repository getInstance(Context context) {
if (mInstance == null) {
mInstance = new Repository(context.getApplicationContext());
}
return mInstance;
}
private Repository(Context context) {
super(context, DATABASE_NAME, null, VERSION);
this.mContext = context;
SQLiteDatabase db = null;
try {
db = getReadableDatabase();
if (db != null) {
db.close();
}
DATABASE_FILE = context.getDatabasePath(DATABASE_NAME);
if (mInvalidDatabaseFile) {
copyDatabase();
}
if (mIsUpgraded) {
doUpgrade();
}
} catch (SQLiteException e) {
} finally {
if (db != null && db.isOpen()) {
db.close();
}
}
}
#Override
public void onCreate(SQLiteDatabase db) {
mInvalidDatabaseFile = true;
}
#Override
public void onUpgrade(SQLiteDatabase database,
int old_version, int new_version) {
mInvalidDatabaseFile = true;
mIsUpgraded = true;
}
/**
* called if a database upgrade is needed
*/
private void doUpgrade() {
// implement the database upgrade here.
}
#Override
public synchronized void onOpen(SQLiteDatabase db) {
super.onOpen(db);
// increment the number of users of the database connection.
mOpenConnections++;
if (!db.isReadOnly()) {
// Enable foreign key constraints
db.execSQL("PRAGMA foreign_keys=ON;");
}
}
/**
* implementation to avoid closing the database connection while it is in
* use by others.
*/
#Override
public synchronized void close() {
mOpenConnections--;
if (mOpenConnections == 0) {
super.close();
}
}
private void copyDatabase() {
AssetManager assetManager = mContext.getResources().getAssets();
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(DATABASE_NAME);
out = new FileOutputStream(DATABASE_FILE);
byte[] buffer = new byte[1024];
int read = 0;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
} catch (IOException e) {
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {}
}
}
setDatabaseVersion();
mInvalidDatabaseFile = false;
}
private void setDatabaseVersion() {
SQLiteDatabase db = null;
try {
db = SQLiteDatabase.openDatabase(DATABASE_FILE.getAbsolutePath(), null,
SQLiteDatabase.OPEN_READWRITE);
db.execSQL("PRAGMA user_version = " + VERSION);
} catch (SQLiteException e ) {
} finally {
if (db != null && db.isOpen()) {
db.close();
}
}
}
}
All you need to do is put the sqlite database in your assets folder, then when your app starts the first time, copy the database over to the SDCard.
Here is a great description of how to do this.
Android uses internal databases for SQLite. If you want to use an external SQLite database (or any other external database) you're going to need to use something like an HHTP proxy. Here's a link that provides more info: https://stackoverflow.com/a/4124829/1852466
I have a problem with my Android application. I'm using code bellow to opening SQLite database in AsyncTask. Everything works fine but when I try to close database in onStop() or onDestroy method, it's never closed.
Code for creating and opening database:
public class SQLiteDB extends SQLiteOpenHelper{
private final Context context;
private SQLiteDatabase sqliteDatabase = null;
public SQLiteDB(Context context, String DBName) {
super(context, DBConstant.DB_NAME, null, context.getResources().getInteger(ppredota.android.navigation.view.activities.R.string.database_version));
this.context = context;
}
public void createDB() throws IOException{
if(existDB()){
this.getReadableDatabase();
this.close();
}
else {
this.getWritableDatabase();
try {
copyDB();
this.close();
}
catch (Exception e) {
throw new Error("Chyba pri kopirovani databaze");
}
}
}
private boolean existDB() {
SQLiteDatabase checkDatabase = null;
try{
String fullPath = DBConstant.DB_PATH + DBConstant.DB_NAME;
checkDatabase = SQLiteDatabase.openDatabase(fullPath, null, SQLiteDatabase.OPEN_READWRITE);
}
catch (SQLiteException sqle) {
Log.i("existDB()", "Databaze nelze otevrit, neexistuje");
}
if(checkDatabase == null){
Log.i("existDB", "Databaze jeste neexistuje...");
return false;
}
else{
Log.i("existDB", "Databaze uz existuje...");
checkDatabase.close();
return true;
}
}
private void copyDB() throws IOException {
InputStream inDBStream = context.getAssets().open(DBConstant.DB_NAME);
String newDBPath = DBConstant.DB_PATH + DBConstant.DB_NAME;
OutputStream outDBStream = new FileOutputStream(newDBPath);
Log.i("copyDB", "Otevren outputstream s cestou k nove databazi");
byte[] buffer = new byte[1024];
int length;
while ((length = inDBStream.read(buffer))>0){
outDBStream.write(buffer, 0, length);
}
outDBStream.flush();
outDBStream.close();
inDBStream.close();
}
public void openDB() throws SQLException {
String fullPath = DBConstant.DB_PATH + DBConstant.DB_NAME;
if(sqliteDatabase!=null){
if(sqliteDatabase.isOpen()){
Log.i("openDB()", "Databaze je jiz otevrena");
}
else{
sqliteDatabase = SQLiteDatabase.openDatabase(fullPath, null, SQLiteDatabase.OPEN_READONLY);
Log.i("openDB()", "Databaze" + sqliteDatabase.getPath() + "otevrena");
}
}
else{
sqliteDatabase = SQLiteDatabase.openDatabase(fullPath, null, SQLiteDatabase.OPEN_READONLY);
if(sqliteDatabase.isOpen()){
Log.i("openDB()", "Databaze otevrena");
}
}
}
#Override
public void close() {
if(sqliteDatabase!=null){
sqliteDatabase.close();
Log.i("close()", "Databaze zavrena");
}
super.close();
}
public SQLiteDatabase getSQLiteDatabase() {
if(sqliteDatabase==null){
Log.i("getSQLiteDatabase()","Problem, vraci sqliteDatabase = null");
}
else{
Log.i("getSQLiteDatabase()","instance sqliteDatabase vracena bez problemu");
}
return sqliteDatabase;
}
AssyncTask class:
public class OpenDatabaseTask extends AsyncTask {
private Context context;
private SQLiteDB sqliteDB;
public OpenDatabaseTask(Context context,SQLiteDB sqliteDB) {
this.context = context;
this.sqliteDB = sqliteDB;
}
#Override
protected Void doInBackground(Void... params) {
publishProgress();
try {
sqliteDB.createDB();
} catch (IOException e) {
e.printStackTrace();
}
sqliteDB.openDB();
return null;
}
#Override
protected void onProgressUpdate(Void...unused){
Log.i(OpenDatabaseTask.class.toString(), "Spusteno vlakno");
}
}
and Activity (only important part):
private SQLiteDB sqliteDB;
private SQLiteData sqliteData;
private OpenDatabaseTask openDatabaseTask;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.navigatemenu);
sqliteDB = new SQLiteDB(getApplicationContext(), sourceDatabaseName);
openDatabaseTask = new OpenDatabaseTask(getApplicationContext(), sqliteDB);
openDatabaseTask.execute();
protected void onDestroy(){
super.onDestroy();
Log.i("onDestroy()", "Pokus o zavreni databaze");
//here is the problem, database never closed
sqliteDB.close();
}
protected void onStop(){
super.onStop();
Log.i("onStop()", "Pokus o zavreni databaze");
//here is the problem, database never closed
sqliteDB.close();
}
protected void onPause(){
super.onPause();
}
protected void onResume(){
super.onResume();
//Log.i("onResume()", "Pokus o otevreni databaze");
}
}
So when I try use a close() method to closing database, sqliteDatabase is always null and database is never closed. So database is still opened and after calling onDestroy exception occurs.
Thank you for your time and sorry for my english, I'm czech :)
Just a guess (assuming you want to close on destroy)
close the database before calling the super
protected void onDestroy(){
// close befor super is called
sqliteDB.close();
super.onDestroy();
Log.i("onDestroy()", "Pokus o zavreni databaze");
// sqliteDB.close(); // super.onDestroy may already has destroyed the DB
}
Note:
Assuming that the database only exists and is open while the activity is visible you should open the database in onResume() and close it in onPause().
If the database should be open when the code is loaded into memory create it in onCreate and close it in onDestroy
In your example you open it in onCreate and close it in onStop. Problem: when the activity becomes visible for the 2nd time the db is closed.
For details see android activity documentation and look into the Application-Lifecycle at the button.
I have an app with heavy db interaction. I didnt user helper. My db is opened lots of times, in UI thread and in background thread too, but never ever closed. Had no problems so far, dont know if it is the right way to do...
I am trying to make an Android music player. To make things easier, I have decided to copy the Artists on the phone to a local DB and then make some custom queries to the local data. I know how to copy the managedQuery to a db, but cannot do so on an AsyncTask since managedQuery is only accessible by an Activity class. I am trying to do this call in my Application class upon app startup. Does anyone know a way to call managedQuery inside of the AsyncTask? I really do not want to do this in my first activity that is called since it will slow my load speed significantly.
This is what I would like to do, although I know this will not compile...
public class AplayApplication extends Application implements
OnSharedPreferenceChangeListener {
private static final String TAG = AplayApplication.class.getSimpleName();
private SharedPreferences prefs;
protected MusicData musicData;
protected PlayerHandler mMediaPlayer;
protected boolean isPlaying;
private boolean prefUseDefaultShuffle;
private boolean prefUseSmartShuffle;
private int prefArtistSkipDuration;
private int prefUnheardArtistPct;
protected TabHost tabHost;
protected Song currentSong;
protected int currentSongPosition;
private static final String PREFERENCE_KEY = "seekBarPreference";
protected boolean hasLoadedSongs;
private static AplayApplication aplayapp;
#Override
public void onCreate() {
super.onCreate();
prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
setPrefs();
Log.i(TAG, "Application started");
mMediaPlayer = new PlayerHandler();
// code in question below this line
musicData = new MusicData(this); // this creates instance of database helper to access db
// will call execute on async task here.
// new getArtist().execute();
}
private class getArtists extends AsyncTask<Void, Void, Boolean>{
Cursor artCursor;
#Override
protected Boolean doInBackground(Void... params) {
String[] proj = {
MediaStore.Audio.Artists._ID,MediaStore.Audio.Artists.ARTIST,
};
artCursor = managedQuery(
MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, proj, null,
null, MediaStore.Audio.Artists.ARTIST + " ASC");
ContentValues values = new ContentValues();
artCursor.moveToPosition(-1);
while (artCursor.moveToNext()) {
values.put(
MusicData.S_DISPLAY,
newMusicCursor.getString(newMusicCursor
.getColumnIndex(MediaStore.Audio.Media.DISPLAY_NAME)));
values.put(MusicData.S_ARTIST, newMusicCursor
.getString(newMusicCursor
.getColumnIndex(MediaStore.Audio.Media.ARTIST)));
values.put(MusicData.S_FILE, newMusicCursor
.getString(newMusicCursor
.getColumnIndex(MediaStore.Audio.Media.DATA)));
this.musicData.insertMastSong(values);
}
return true;
}
//// code continues.....
As Sparky says, you could use CursorLoader instead of managedQuery.
If you are developing for sdk 8 you need to add Support Package to your project.
To avoid delay your application start maybe you could use a Service.
This is a little example for use a service, get the data from an url and then insert it to the database
public class GetArticlesService extends IntentService {
private static final String TAG = "GetArticlesService";
public GetArticlesService() {
super("GetdArticlesService");
}
/* (non-Javadoc)
* #see android.app.IntentService#onHandleIntent(android.content.Intent)
*/
#Override
protected void onHandleIntent(Intent intent) {
String url = "http://example.com/artists.json";
String response = null;
try {
response = Utils.httpPost(getApplicationContext(), url + "/api/GetArticles", null);
} catch (HttpHostConnectException e) {
e.printStackTrace();
}
if(!TextUtils.isEmpty(response)){
try {
JSONArray list = new JSONArray(response);
if(list.length() > 0){
ContentValues toInsert = new ContentValues[];
JSONObject art = null;
int cant = list.length();
for(int i = 0;i< cant; i++){
toInsert.clear();
art = list.getJSONObject(i);
toInsert = new ContentValues();
toInsert.put(Articles._ID, art.getInt("id"));
toInsert.put(Articles.DESCRIPTION, art.getString("description"));
toInsert.put(Articles.BARCODE, art.getString("barcode"));
toInsert.put(Articles.RUBRO, art.getString("rubro"));
toInsert.put(Articles.CLAVE, art.getString("clave"));
getContentResolver().inert(Articles.CONTENT_URI, toInsert);
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
managedQuery is deprecated. Use CursorLoader instead.
I face two main problems when using a sqlite command inside an AsncTask in android.
When I execute a select command on the first try I get no results but on the second try (loading a activity that has this Asynctask) I do get results.
Sometimes I get an error that the database is not closed despite that it is already closed/
What is the problem with this?
UPDATE:
This is the code that retrive data from database (db.getAllMessage)
private ArrayList<FriendMessagesResulted> getMessagesFromCach(Context c){
FriendMessagesResulted messagesResulted1 = new FriendMessagesResulted();
DBAdapter db = new DBAdapter(c);
Cursor c1;
db.open();
c1 = db.getAllMessage(Settings.getCurrentUserId(c),Integer.parseInt(fId));
Log.d("***Database count",c1.getCount()+" from: "+Settings.getCurrentUserId(c)+" to:"+Integer.parseInt(fId));
c1.moveToFirst();
if(c1.getCount()>0)
status=true;
if (messagesResultedList == null) {
messagesResultedList = new ArrayList<FriendMessagesResulted>();
}
else
messagesResultedList.clear();
while (c1.isAfterLast() == false) {
if(Integer.parseInt(c1.getString(0))>maxId)
maxId=Integer.parseInt(c1.getString(0));
messagesResulted1.set_mId(Integer.parseInt(c1.getString(0)));
messagesResulted1.set_msgTxt("MD:"+c1.getString(3));
messagesResulted1.set_MessageTime(c1.getString(4));
messagesResulted1.set_dir(c1.getString(5));
messagesResultedList.add(messagesResulted1);
c1.moveToNext();
}
db.close();
c1.close();
return messagesResultedList;
}
and this the code for AsyncTask, where I call get getMessagesFromCach method
private void getMessages(final Context c)
{
handler = new Handler();
r=new Runnable() {
public void run() {
class RecentMessageLoader extends AsyncTask<Void, Void, ArrayList<FriendMessagesResulted>>{
ArrayList<FriendMessagesResulted> messagesResultedList=null;
#Override
protected ArrayList<FriendMessagesResulted> doInBackground(Void... params) {
if(!finishLoadingPastMessages)
{
messagesResultedList=getMessagesFromCach(c);
if(!status){
Log.d("Where are you","I'm in JSON");
messagesResultedList=getMessagesFromJSON(c);
}
}
else{
Log.d("Where are you","I'm in Recent messages");
messagesResultedList=getRecentMessages(c,Settings.getCurrentUserId(c),Integer.parseInt(fId));
}
return messagesResultedList;
}
protected void onPostExecute( ArrayList<FriendMessagesResulted> FMRList ) {
// to disappear loading message
d.dismiss();
finishLoadingPastMessages=true;
if(FMRList!=null){
for(int i=FMRList.size()-1;i>=0;i--)
addMessage(FMRList.get(i),c);
}
handler.postDelayed(r, 2000);
}
}
new RecentMessageLoader().execute();
}
};
handler.post(r);
}
UPDATE 2 : Cach class ..
public class Cach {
static DBAdapter db;
public Cach(Context c)
{
}
public static void AddMessages(Context c,
int id,
int fromId,
int toId,
String message,
String dir,
String MessageTime)
{
db = new DBAdapter(c);
db.open();
long id2;
id2 = db.insertMessage(id, fromId, toId, message, dir,MessageTime);
db.close();
}
}
It seems the problem is with the type of variables you are using.. there must be Static variables of instance variables which are getting set from many sources... try not to use static variables and use local variables I mean in the methods implicitly.
I'm creating an application. I'm getting this error:
11-08 13:46:24.665: ERROR/Database(443):
java.lang.IllegalStateException:
/data/data/com.testproj/databases/Testdb SQLiteDatabase created and
never closed
I can't seem to find the reason for this, as it somethimes shows me the error, sometimes not. Here is my code:
public class SQLiteAssistant extends SQLiteOpenHelper {
public SQLiteAssistant(Context context){
super(context, DB_NAME, null, DB_VERSION_NUMBER);
this.myContext = context;
}
public void openDataBase() throws SQLException{
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
public void closeDataBase() {
if(this.myDataBase != null) {
if(this.myDataBase.isOpen())
this.myDataBase.close();
}
}
}
}
In another class, I have these queries:
public class Db{
private static SQLiteAssistant sqlite;
public static String getSomeString(Context ctx) {
sqlite = new SQLiteAssistant(ctx);
sqlite.openDataBase();
Cursor cursor = sqlite.myDataBase.rawQuery("SELECT someColumn from SomeTable",null);
if (cursor != null) {
if (cursor.getCount()==1) {
if(cursor.moveToFirst()) {
String testString = cursor.getString(cursor.getColumnIndex("someColumn"));
cursor.close();
sqlite.closeDataBase();
sqlite.close();
return testString
}
}
}
sqlite.closeDataBase();
sqlite.close();
return null;
}
}
My problem is when I start a new activity in which I get an AsyncTask. This task gets data from a web service and accesses the database for the String. Here is the AsyncTask:
protected class BackTask extends AsyncTask<Context, String, String> {
#Override
protected String doInBackground(Context... params) {
try{
//get requeste data from the database
//access the web service
return result;
} catch (Exception e) {
return null;
}
return null;
}
}
If I let the activity take its course, everything goes fine. If I don't and quickly press the back button, I get the error. Any suggestion on how to solve this problem?
Am not sure you're using SQLiteOpenHelper properly... you don't need that myDataBase field, the idea is that it manages your database connection for you. Don't subclass in that way... unless you're doing things in onCreate() etc that aren't posted here it looks like you can just use SQLiteOpenHelper directly, i.e.:
SQLiteOpenHelper sqlite = new SQLiteOpenHelper(ctx, DB_PATH+DB_NAME, null,
DB_VERSION_NUMBER);
Assuming that ending the activity should also stop your background task, I'd recommend calling AsyncTask.cancel(true) from your Activity.onPause(). Ensure the database is cleaned up from onCancelled().
And if your background task is the only thing reading the database then make it own the SQLiteOpenHelper instance. It's easy to get into trouble with static data, so it's best avoided IMHO. I'd do something like this:
protected class BackTask extends AsyncTask<String, Integer, String>
{
private SQLiteOpenHelper sqlite;
public void BackTask(Context ctx) {
sqlite = new SQLiteOpenHelper(ctx, DB_PATH+DB_NAME, null,
DB_VERSION_NUMBER);
}
#Override
protected String doInBackground(String... params)
{
try {
//get requeste data from the database
//access the web service
return result;
} catch (Exception e) {
}
return null;
}
#Override
protected void onCancelled() {
sqlite.close();
}
#Override
protected void onPostExecute(String result)
sqlite.close();
// Update UI here
}
}
I think this part :
cursor.close();
sqlite.closeDataBase();
sqlite.close();
must be in a finally close like
Try{
//Do something
}
catch(){
//Catch exception
}
finally{
//Close cursor or/and eventually close database if you don't need it in the future
}
Also don't forget to close database in onDestroy method .
onCreate(Bundle b){
//create database instance
}
onDestroy{
//close db
}