gpt4 book ai didi

java - 从未在数据库上明确调用过 Close

转载 作者:行者123 更新时间:2023-11-29 21:17:10 24 4
gpt4 key购买 nike

这个问题已经被问过很多次了,我觉得我的情况有点不一样。

早些时候我在类级别声明了我的 db 对象:

DBAdapter dbHelper; 

在onCreate中:

dbHelper = new DBAdapter(this);

我在销毁时关闭了数据库:

@Override
public void onDestroy(){
super.onDestroy();
if (dbHelper != null)
{
dbHelper.close();
}

}

然而,每次我写入数据库时​​它都会引发错误。在 close 从未在 DB 上显式调用之后它也有一些关于 DB 锁的异常。

问题

我有一个异步任务,在此我为每条记录一个接一个地更新三个表。 (操作确实很大)但是现在我将 DB init 的代码转移到了我的异步任务中。在执行前我初始化数据库,然后在 onPostExecute 中关闭数据库。但是问题仍然存在,有什么办法可以解决这个问题?下面是我的异步任务的代码:

private class MagicCall extends AsyncTask<Void, String, String> {

int years;
long secon;
long min;
int hours;
int mon;
int days;
int weeks;
String CONTACT_ID,CONTACT_NAME,CONTACT_IMAGE_URI;

ProgressDialog Asycdialog = new ProgressDialog(LoaderClass.this);

@Override
protected void onPreExecute() {
dbHelper = new DBAdapter(getApplicationContext());
dbHelper.open();
//Init the LoaderDialog
Asycdialog.setMessage("Working");
Asycdialog.getWindow().setGravity(Gravity.CENTER_VERTICAL);
Asycdialog.getWindow().setGravity(Gravity.CENTER_HORIZONTAL);
Asycdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
Asycdialog.setCancelable(false);
//Dialog Show
Asycdialog.show();
super.onPreExecute();
}

protected void onPostExecute(String result) {
// hide the dialog
dbHelper.close();
Asycdialog.dismiss();
startActivity(new Intent(LoaderClass.this, MainActivity.class));
finish();
super.onPostExecute(result);
}

@Override
protected String doInBackground(Void... args) {


//
// Dear maintainer:
//
// Once you are done trying to 'optimise' this routine,
// and have realized what a terrible mistake that was,
// please increment the following counter as a warning
// to the next guy:
//
// total_hours_wasted_here = 0;
//
int lines = 0;
try{
BufferedReader reader;
if(FLAG ==1){
reader = new BufferedReader(new FileReader("/sdcard/BirthdayReminders/fileone.txt"));
}else{
reader = new BufferedReader(new FileReader("/sdcard/BirthdayReminders/output.txt"));
}
while (reader.readLine() != null) lines++;
reader.close();
}catch(Exception e){

}



dbHelper.NotificationDrop();
int i=0;
File toRead = null;
try{
if(FLAG ==1){
toRead=new File("/sdcard/BirthdayReminders/fileone.txt");
}else{
toRead=new File("/sdcard/BirthdayReminders/output.txt");
}
FileInputStream fis=new FileInputStream(toRead);

Scanner sc=new Scanner(fis);

//read data from file line by line:
String currentLine;
while(sc.hasNextLine()){


currentLine=sc.nextLine();
//now tokenize the currentLine:
StringTokenizer st=new StringTokenizer(currentLine,"=",false);
//put tokens ot currentLine in map
// mapInFile.put(st.nextToken(),st.nextToken());

String dateStr = st.nextToken();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date = format.parse(dateStr);
java.sql.Date dx = new java.sql.Date(date.getTime());
Date key = dx;
String dateToInsert = String.valueOf(dx);
// *********
String listStr = st.nextToken();

String cut = listStr.substring(1, listStr.length() - 1);

String[] array = cut.split(",");
CONTACT_ID = (array[0].trim());

CONTACT_NAME = toTitleCase(array[1].trim());

if(array[2].contains(".jp"))
array[2] = array[2].replace(".jp", ".jpg").trim();
CONTACT_IMAGE_URI = (array[2].trim());


if (isCancelled()) {
break;
}
// int k = Sx.size();


String progress = ("" + Character.toUpperCase(CONTACT_NAME.charAt(0)) + CONTACT_NAME.substring(1) + "\n"+i + " of " + lines + " Contacts"); // Progress displayed here.



years = getDiffYear(key); // For years elapsed
secon = seconds(key); // for seconds elapsed
min = seconds(key) / 60; // For minutes elapsed
hours = (int) (seconds(key) / 60) / 60; // For hours elapsed
mon = months(String.valueOf(key)); // for months elapsed

days = daysElapsed(key); // Days elapsed
weeks = daysElapsed(key) / 7; // For weeks

//===============================================================================================================
if (dateToInsert.contains("0001-") == true){ //Special Case, we added 0001 to Birthdays Which Have NO Year field.
//===========================================================================================================

dbHelper.insert(dateToInsert, CONTACT_NAME, "","", CONTACT_IMAGE_URI, "", "", "", CONTACT_ID, "", ""); // All other fields will be empty, because we don't have a Year.
int PRIMARY_ID = dbHelper.getPrimaryId();
String FOREIGN_KEY = dbHelper.getHighestID(PRIMARY_ID);


//=====================================================================================================
//In this case we are only interested in fetching the year alert for next birthday of this contact -->
//=====================================================================================================

intCal.yearsToNotify(years, dateToInsert);
int yearsSpecial = intCal.getYearsRegular();
Date dateYearsReg = intCal.getYearsRegDate();

dbHelper.insertNotifications(5, convertDate(dateYearsReg), 0, yearsSpecial,FOREIGN_KEY,PRIMARY_ID);

}
//=========================================================================
//Case when all the Date fields exist and we set up notifications --->
//=========================================================================
else if(dateToInsert != "null" && dateToInsert.contains("0001-") != true){

dbHelper.insert(dateToInsert, CONTACT_NAME, String.valueOf(days), String.valueOf(hours), CONTACT_IMAGE_URI, String.valueOf(min),String.valueOf(mon), String.valueOf(secon), CONTACT_ID, String.valueOf(weeks), String.valueOf(years));

int PRIMARY_ID = dbHelper.getPrimaryId(); // Fetch the PrimaryId (_id) of the above inserted row, its the Foreign key for Notification and SpecialNotifications Table.
String FOREIGN_KEY = dbHelper.getHighestID(PRIMARY_ID); // Same as above, but fetches the Name field of the last inserted row.



//=========================================================================
//**Database Insertions Notifications Table/ SpecialNotifications Table**
//=========================================================================



//=======================================================================================//
//Regular intervals DB Insertions:
//======================================================================================//
//Notification Types:
//1 for months
//2 for weeks
//3 for days
//4 for minutes
//5 for years
//6 for seconds
//7 for hours
//======================================================================================//

//==============================
//For Months
//==============================
intCal.monthsNotify(mon, dateToInsert);
int monSpecial = intCal.getMonthRegular();
Date dateMonReg = intCal.getMonRegDate();


dbHelper.insertNotifications(1, convertDate(dateMonReg), 0, monSpecial,FOREIGN_KEY,PRIMARY_ID);


//===============================
//For Weeks
//===============================
intCal.weeksToNotify(weeks,dateToInsert);
int weekSpecial = intCal.getWeekRegular();
Date dateWeekReg =intCal.getWeekRegDate();

dbHelper.insertNotifications(2, convertDate(dateWeekReg), 0, weekSpecial,FOREIGN_KEY,PRIMARY_ID);


//===============================
//For Days
//===============================
intCal.daysToNotify(days, dateToInsert);
int daysSpecial= intCal.getDaysRegular();
Date dateDaysReg = intCal.getDaysRegDate();

dbHelper.insertNotifications(3, convertDate(dateDaysReg), 0, daysSpecial,FOREIGN_KEY,PRIMARY_ID);


//===============================
//For minutes
//===============================
intCal.minutesToNotify(min,dateToInsert);
long minutesSpecial= intCal.getMinutesRegular();
Date dateMinsReg = intCal.getMinutesRegDate();

dbHelper.insertNotifications(4, convertDate(dateMinsReg), 0,(int) minutesSpecial,FOREIGN_KEY,PRIMARY_ID);


//==============================
//For Years
//==============================
intCal.yearsToNotify(years, dateToInsert);
int yearsSpecial = intCal.getYearsRegular();
Date dateYearsReg = intCal.getYearsRegDate();

dbHelper.insertNotifications(5, convertDate(dateYearsReg), 0, yearsSpecial,FOREIGN_KEY,PRIMARY_ID);


//=============================
//For Seconds
//=============================
intCal.secondsToNotify(secon, dateToInsert);
long secondsSpecial= intCal.getSecondsRegular();
Date dateSecondsReg = intCal.getSecondsRegDate();

dbHelper.insertNotifications(6, convertDate(dateSecondsReg), 0, secondsSpecial,FOREIGN_KEY,PRIMARY_ID);


//=============================
//For Hours
//=============================
intCal.hoursToNotify(hours, dateToInsert);
int hoursSpecial= intCal.getHoursRegular();
Date dateHoursReg= intCal.getHoursRegDate();

dbHelper.insertNotifications(7, convertDate(dateHoursReg), 0, hoursSpecial,FOREIGN_KEY,PRIMARY_ID);



//============================================================================================//
//Special Intervals
//=============================================================================================================//
//Notification Types:
//1 for months
//2 for weeks
//3 for days
//4 for minutes
//5 for years
//6 for seconds
//7 for hours
//For Years
intCal.specialIntervalYears(years, dateToInsert);
int yearsOnceSpecial =intCal.getYearsSpecial();
Date dateYearsSpecial = intCal.getYearsSpDate();
dbHelper.insertSpecialNotifications(5, convertDate(dateYearsSpecial), yearsOnceSpecial,FOREIGN_KEY,PRIMARY_ID);


//For Months
intCal.specialIntervalMonths(mon,dateToInsert);
int monthsOnceSpecial= intCal.getMonthsSpecial();
Date dateMonthsSpecial = intCal.getMonthsSpDate();
dbHelper.insertSpecialNotifications(1, convertDate(dateMonthsSpecial), monthsOnceSpecial,FOREIGN_KEY,PRIMARY_ID);


//For Weeks
intCal.specialIntervalsWeeks(weeks,dateToInsert);
int weeksOnceSpecial= intCal.getWeeksSpecial();
Date dateWeeksSpecial = intCal.getWeeksSpDate();
dbHelper.insertSpecialNotifications(2, convertDate(dateWeeksSpecial), weeksOnceSpecial,FOREIGN_KEY,PRIMARY_ID);

//For Days
intCal.specialIntervalsDays(days, dateToInsert);
int daysOnceSpecial= intCal.getDaysSpecial();
Date dateDaysSpecial = intCal.getDaysSpDate();
dbHelper.insertSpecialNotifications(3, convertDate(dateDaysSpecial), daysOnceSpecial,FOREIGN_KEY,PRIMARY_ID);

//For Hours
intCal.specialIntervalsHours(hours,dateToInsert);
int hoursOnceSpecial= intCal.getHoursSpecial();
Date dateHoursSpecial = intCal.getHoursSpDate();
dbHelper.insertSpecialNotifications(7, convertDate(dateHoursSpecial), hoursOnceSpecial,FOREIGN_KEY,PRIMARY_ID);

//For Minutes
intCal.specialIntervalMinutes(min,dateToInsert);
long minutesOnceSpecial= intCal.getMinutesSpecial();
Date dateMinutesSpecial= intCal.getMinutesSpDate();
dbHelper.insertSpecialNotifications(4, convertDate(dateMinutesSpecial), (int)minutesOnceSpecial,FOREIGN_KEY,PRIMARY_ID);

//For Seconds
intCal.specialIntervalsSeconds(secon,dateToInsert);
long secondsOnceSpecial= intCal.getSecondsSpecial();
Date dateSecondsSpecial= intCal.getSecondsSpDate();
dbHelper.insertSpecialNotifications(6, convertDate(dateSecondsSpecial), secondsOnceSpecial,FOREIGN_KEY,PRIMARY_ID);

}
publishProgress(progress);
Asycdialog.setMax(lines);
Asycdialog.incrementProgressBy(1);
i++;
}

}catch (Exception e){

}
try{
writeToSD();
}catch (Exception e){
System.out.println(""+e);
}


return "";

}

protected void onProgressUpdate(String... values) {

super.onProgressUpdate(values);
Asycdialog.setMessage("" + values[0]);
}


}

这是日志:

01-15 09:22:36.215: E/SQLiteDatabase(728): close() was never explicitly called on database '/data/data/com.exa.birthdayrem/databases/Bdr' 
01-15 09:22:36.215: E/SQLiteDatabase(728): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1943)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1007)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:986)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1051)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:770)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:221)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157)
01-15 09:22:36.215: E/SQLiteDatabase(728): at com.exa.birthdayrem.DBAdapter.<init>(DBAdapter.java:110)
01-15 09:22:36.215: E/SQLiteDatabase(728): at com.exa.birthdayrem.LoaderClass$MagicCall.onPreExecute(LoaderClass.java:378)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:561)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.os.AsyncTask.execute(AsyncTask.java:511)
01-15 09:22:36.215: E/SQLiteDatabase(728): at com.exa.birthdayrem.LoaderClass.onLoadFinished(LoaderClass.java:225)
01-15 09:22:36.215: E/SQLiteDatabase(728): at com.exa.birthdayrem.LoaderClass.onLoadFinished(LoaderClass.java:1)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:433)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:405)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.content.Loader.deliverResult(Loader.java:110)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.content.CursorLoader.deliverResult(CursorLoader.java:88)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.content.CursorLoader.deliverResult(CursorLoader.java:42)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:236)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:76)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.os.AsyncTask.finish(AsyncTask.java:602)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.os.AsyncTask.access$600(AsyncTask.java:156)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.os.Handler.dispatchMessage(Handler.java:99)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.os.Looper.loop(Looper.java:137)
01-15 09:22:36.215: E/SQLiteDatabase(728): at android.app.ActivityThread.main(ActivityThread.java:4340)
01-15 09:22:36.215: E/SQLiteDatabase(728): at java.lang.reflect.Method.invokeNative(Native Method)
01-15 09:22:36.215: E/SQLiteDatabase(728): at java.lang.reflect.Method.invoke(Method.java:511)
01-15 09:22:36.215: E/SQLiteDatabase(728): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
01-15 09:22:36.215: E/SQLiteDatabase(728): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
01-15 09:22:36.215: E/SQLiteDatabase(728): at dalvik.system.NativeStart.main(Native Method)
01-15 09:22:36.215: E/System(728): Uncaught exception thrown by finalizer
01-15 09:22:36.235: E/System(728): java.lang.IllegalStateException: Don't have database lock!
01-15 09:22:36.235: E/System(728): at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2090)
01-15 09:22:36.235: E/System(728): at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2182)
01-15 09:22:36.235: E/System(728): at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2178)
01-15 09:22:36.235: E/System(728): at android.util.LruCache.trimToSize(LruCache.java:197)
01-15 09:22:36.235: E/System(728): at android.util.LruCache.evictAll(LruCache.java:285)
01-15 09:22:36.235: E/System(728): at android.database.sqlite.SQLiteDatabase.deallocCachedSqlStatements(SQLiteDatabase.java:2143)
01-15 09:22:36.235: E/System(728): at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:1126)
01-15 09:22:36.235: E/System(728): at android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:1914)
01-15 09:22:36.235: E/System(728): at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:182)
01-15 09:22:36.235: E/System(728): at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168)
01-15 09:22:36.235: E/System(728): at java.lang.Thread.run(Thread.java:856)

DBAdapter中的open方法:

public DBAdapter open() throws SQLException {
DBHelper = new DatabaseHelper(mCtx);
mDb = DBHelper.getWritableDatabase();
return this;

}

最佳答案

我通常在每个方法的 finally block 中关闭数据库。喜欢关注

try {
//open db
// perform tasks
} catch (Exception e) {
// handle exceptions
} finally {
// close db
}

关于java - 从未在数据库上明确调用过 Close,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21128733/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com