SQLiteOpenHelper.getWritableDatabase problem
EDIT: I believe i may have found the problem. I need to work on my SmartDBHelper class. Will do this and post the results here.
EDIT: Found a link to someone who is having similar problem. Will be checking this to see if it fixes asap. Another Post
EDIT: Updated to reflect some changes made suggested by some of the posters. Problem is still occurring.
THE POST BELOW:
My application need to be able to write to the sqlite3 database that is on the android from 2 different events. One of my events is writing to the database just fine. When the second event tries to write to the database the attached error occurs. I have no clue why this is happening or how to fix it. I have tried numerous things the past couple hours and googled a ton. Can someone please view the code i have below and let me know what you think?
If you need any more information please let me know asap.
Thanks in advance!
//This is the sqliteopenhelper i created
public class SmartDBHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "smart_lite_db.db";
private static final int DATABASE_VERSION = 2;
private static final String NOTIFY_TABLE_NAME = "user_notify_data";
private static final String HR_TABLE_NAME = "user_hr_data";
private static final String NOTIFY_TABLE_CREATE =
"CREATE TABLE " + NOTIFY_TABLE_NAME +
" (counter INTEGER PRIMARY KEY, " +
"userresponse INTEGER, " +
"notifytime INTEGER);";
private static final String DATA_TABLE_CREATE =
"CREATE TABLE " + HR_TABLE_NAME +
" (counter INTEGER PRIMARY KEY, " +
"hr INTEGER, " +
"act INTEGER, " +
"timestamp INTEGER);";
public SmartDBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
Log.v("smartdbhelper", "before creation");
db.execSQL(NOTIFY_TABLE_CREATE);
Log.v("smartdbhelper", "middle creation");
db.execSQL(DATA_TABLE_CREATE);
Log.v("smartdbhelper", "after creation");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
//This is the part that is working CORRECTLY
public class DataNotificationSurvey extends Activity {
private SmartDBHelper dBHelper;
private Date timeStamp;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.datanotificationlayout);
Log.v("datanotificationsurvey", "inside datanotificationsurvey");
dBHelper = new SmartDBHelper(this);
timeStamp = new Date(DataNotification.when);
// XML code stuff left out here, was not needed
}
public void submitNotify(int tempType, Date tempDate) {
SQLiteDatabase dBH = dBHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("userresponse", tempType);
values.put("notifytime", (tempDate.getTime()/1000));
dBH.insert("user_notify_data", null, values);
dBH.close();
}
}
// This is the event that is NOT working correctly
public class DataBuilder extends Activity {
private List _listeners = new ArrayList();
private SmartDataObject data;
Context tThis;
private SmartDBHelper dBHelper;
private Date timeStampReference; //for keeping track of the first time
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v("databuilder", "on create");
dBHelper = new SmartDBHelper(this);
}
public void prepareData(SmartDataObject temp) {
submitData(temp);
}
public void submitData(SmartDataObject temp) {
data = temp;
System.out.println("Where: DB-submitData");
try {
SQLiteDatabase dBH = dBHelper.getWritableDatabase(); // CODE FAILS AT THIS POINT
Log.v("databuilder", "after writable");
ContentValues values = new ContentValues();
values.put("hr", data.getHeartRate());
values.put("act", data.getAct());
values.put("timestamp", data.getTimeStamp());
dBH.insert("user_hr_data", null, values);
Log.v("databuilder", "after insert");
dBH.close();
fireDataBuilderEvent(data);
}
catch(SQLException e) {
e.printStackTrace();
}
catch(NullPointerException e) {
e.printStackTrace();
}
}
public synchronized void addDataBuilderListener(DataBuilderListener listener) {
_listeners.add(listener);
}
p开发者_运维问答ublic synchronized void removeDataBuilderListener(DataBuilderListener listener) {
_listeners.remove(listener);
}
private synchronized void fireDataBuilderEvent(SmartDataObject temp) {
DataBuilderEvent dRE = new DataBuilderEvent(this, temp);
Iterator listeners = _listeners.iterator();
while(listeners.hasNext()) {
((DataBuilderListener)listeners.next()).dataBuilderReceived(dRE);
}
}
public interface DataBuilderListener {
public void dataBuilderReceived(DataBuilderEvent event);
}
}
// The error that is occuring.
03-13 17:38:40.130: INFO/System.out(279): Where: DB-submitData
03-13 17:38:40.130: WARN/System.err(279): java.lang.NullPointerException
03-13 17:38:40.151: WARN/System.err(279): at cpe495.smartapp.DataBuilder.submitData(DataBuilder.java:41)
03-13 17:38:40.151: WARN/System.err(279): at cpe495.smartapp.DataBuilder.prepareData(DataBuilder.java:34)
03-13 17:38:40.171: WARN/System.err(279): at cpe495.smartapp.SmartApp$2.dataAnalyzedReceived(SmartApp.java:56)
03-13 17:38:40.171: WARN/System.err(279): at cpe495.smartapp.DataRobot.fireDataAnalyzedEvent(DataRobot.java:269)
03-13 17:38:40.181: WARN/System.err(279): at cpe495.smartapp.DataRobot.analyzeData(DataRobot.java:79)
03-13 17:38:40.181: WARN/System.err(279): at cpe495.smartapp.SmartApp$1.dataReceivedReceived(SmartApp.java:49)
03-13 17:38:40.191: WARN/System.err(279): at cpe495.smartapp.ConnectDevice.fireDataReceivedEvent(ConnectDevice.java:79)
03-13 17:38:40.201: WARN/System.err(279): at cpe495.smartapp.ConnectDevice.run(ConnectDevice.java:46)
03-13 17:38:40.211: WARN/System.err(279): at java.lang.Thread.run(Thread.java:1096)
A quick guess: change private SmartDBHelper dBHelper = new SmartDBHelper(this);
to just private SmartDBHelper dBHelper;
and only initialize the new object in onCreate().
use SQLiteDatabase's methods to check the database status
isDbLockedByCurrentThread()
isDbLockedByOtherThreads
I think it's lock by another thread. Or check your provider setting in Androidmanifest.xml.
I had this problem and while I wouldn't normally tell anyone to purposely leak anything, this was the only stable quick fix I could think of.
This fixed it for me;
private static YourSQLiteOpenHelper helperAnchor;
And in onCreate
helperAnchor = this;
So basically give the object a reference to itself to keep it alive because in my case there was nowhere else to sensibly put it due to calling my local db from a large number of classes in a ViewPager. This comes with the added downside of having to create another method to set it to null again, which you have to call wherever you want to clean it up.
But hey, it just werks. The application is super stable now where before it would crash on the SQLiteOpenHelper being null at random times. Please tell me if/when there's a better way to do it because quite frankly I don't like using this either.
精彩评论