导入数据库后从未在数据库上显式调用 close()
close() was never explicitly called on database after database is imported
我的应用程序出现以下错误。但是,此错误不会使我的应用程序崩溃。尽管如此,我知道是什么导致了这个错误,但不确定如何修复它。当我更加注意这个错误时,是因为我正在将我的数据库从 Asset 文件夹复制到 /data/ 文件夹。我在整个应用程序中使用相同的代码来确保数据库存在(如果不再次复制)。如果用户误删除了数据库。这就是我使用该代码的原因(我将在错误下方将其传递)。正如我所做的研究,这可能是我的应用程序因内存不足错误而崩溃的原因之一。不确定这是否也会导致内存泄漏。请帮我。就像我之前说的,在出现内存不足错误之前,该应用程序可以正常工作。我想修复从这个错误开始的所有错误。
错误:
01-08 17:22:44.326: E/Database(414): close() was never explicitly called on database '/data/data/com.drakeillusion.yao1/databases/YAOMasterDB.db'
01-08 17:22:44.326: E/Database(414): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
01-08 17:22:44.326: E/Database(414): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810)
01-08 17:22:44.326: E/Database(414): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
01-08 17:22:44.326: E/Database(414): at com.example.yao.YAOMySQLiteHelper.openDataBase(YAOMySQLiteHelper.java:328)
01-08 17:22:44.326: E/Database(414): at com.example.yao.SplashActivity.copydbfromassest(SplashActivity.java:128)
01-08 17:22:44.326: E/Database(414): at com.example.yao.SplashActivity.onCreate(SplashActivity.java:68)
01-08 17:22:44.326: E/Database(414): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-08 17:22:44.326: E/Database(414): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
01-08 17:22:44.326: E/Database(414): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
01-08 17:22:44.326: E/Database(414): at android.app.ActivityThread.access00(ActivityThread.java:125)
01-08 17:22:44.326: E/Database(414): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
01-08 17:22:44.326: E/Database(414): at android.os.Handler.dispatchMessage(Handler.java:99)
01-08 17:22:44.326: E/Database(414): at android.os.Looper.loop(Looper.java:123)
01-08 17:22:44.326: E/Database(414): at android.app.ActivityThread.main(ActivityThread.java:4627)
01-08 17:22:44.326: E/Database(414): at java.lang.reflect.Method.invokeNative(Native Method)
01-08 17:22:44.326: E/Database(414): at java.lang.reflect.Method.invoke(Method.java:521)
01-08 17:22:44.326: E/Database(414): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-08 17:22:44.326: E/Database(414): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-08 17:22:44.326: E/Database(414): at dalvik.system.NativeStart.main(Native Method)
我的活动:
这是我调用的第一个 activity 将数据库从资产文件夹导入到 /data/ 文件夹
public class SplashActivity extends Activity {
String value;
String update = "01";
Boolean mastupdate = false;
private static String DB_PATHNAME = "/data/data/com.example.yao/database/YAOMasterDB.db";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
copydbfromassest();
// Show the splash screen
setContentView(R.layout.activity_splash);
// Find the progress bar
ProgressBar progressBar = (ProgressBar) findViewById(R.id.activity_splash_progress_bar);
// Start your loading
new LoadingTask(progressBar, this).execute("127.0.0.1");
Thread thread = new Thread(){
/////@Override
public void run(){
//TODO Auto-generated nethod stub
//super.run();
try{
sleep(1000);
/////startActivity(new Intent(getApplicationContext(),MainActivity.class));
} catch (InterruptedException e){
//TODO Auto-generated catch block
e.printStackTrace();
//}finally{
// Intent a = new Intent (SplashActivity.this,MainActivity.class);
}
}
};
thread.start();
}
///copy the database from assest folder
private void copydbfromassest() {
// TODO Auto-generated method stub
YAOMySQLiteHelper myhelper = new YAOMySQLiteHelper (this);
try{
//create datbase
myhelper.importIfNotExist();
}catch (IOException e){
throw new Error("Unable to Create the Database ");
}
try{
myhelper.openDataBase();
}catch (SQLException sqle){
throw sqle;
}
}
//// delete the database
private void deletedb() {
// TODO Auto-generated method stub
try{
File f = new File(DB_PATHNAME);
if (f.exists()){
f.delete();
}
}catch (Exception ex){
ex.printStackTrace();
}
}
private void openfilelevel() {
// TODO Auto-generated method stub
FileInputStream fis;
try{
fis = openFileInput("update.ss");
byte [] input = new byte[fis.available()];
while(fis.read(input) != -1){
value = new String (input);
}
fis.close();
if(!value.contentEquals(update)){
mastupdate = true;
createupdatelevel();
}
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
private void createupdatelevel() {
// TODO Auto-generated method stub
String FILENAME = "update.ss";
String JOUR = update;
try{
File file = getBaseContext().getFileStreamPath(FILENAME);
mastupdate = true;
FileOutputStream fos = openFileOutput(FILENAME, getBaseContext().MODE_PRIVATE);
fos.write(JOUR.getBytes());
fos.close();
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
/// text make the file
private void makethefile() {
// TODO Auto-generated method stub
String FILENAME = "Update.ss";
String JOUR = update;
try{
File file = getBaseContext().getFileStreamPath(FILENAME);
if (file.exists()){
Toast.makeText(this, "Exist", Toast.LENGTH_LONG).show();
}else{
mastupdate = true;
FileOutputStream fos = openFileOutput(FILENAME, getBaseContext().MODE_PRIVATE);
fos.write(JOUR.getBytes());
}
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
public void onTaskFinished() {
completeSplash();
}
private void completeSplash(){
startApp();
finish(); // Don't forget to finish this Splash Activity so the user can't return to it!
}
private void startApp() {
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
startActivity(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
这是我的 "DatabaseHelper" 名为 YAOMySQLiteHelper。
YAOMySQLiteHelper 包含很多代码我将通过相应的部分。
public class YAOMySQLiteHelper extends SQLiteOpenHelper {
public static String db_path;
private String dbName;
private String dbNameFK;
private String dbImages;
//private Context context;
private final Context context;
private SQLiteDatabase myDataBase;
private static final String DATABASE_NAMEFK = "YAOMasterDB.jet";
private static final String DATABASE_NAME = "YAOMasterDB.db";
public YAOMySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.dbNameFK = DATABASE_NAMEFK;
this.dbName = DATABASE_NAME;
// this.dbImages=DATABASE_IMAGES;
this.context = context;
db_path = "/data/data/" + context.getPackageName() + "/databases/";
}
public void importIfNotExist() throws IOException {
boolean dbExist = checkExist();
if (dbExist) {
Log.i("Tag : ImportIfNotExist", "DB Exist : " + dbExist);
// do nothing - database already exist
} else {
Log.i("Tag : ImportIfNotExist", "DB Not Exist : " + dbExist);
// By calling this method and empty database will be created into
// the default system path
// of your application so we are gonna be able to overwrite that
// database with our database.
this.getReadableDatabase();
try {
copyDatabase();
//Deleteing a file (Database)
// DeleteDBjet();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/*
* Create a copy of the database from Asset folder to the android emulator
*/
private void copyDatabase() throws IOException {
Log.i("Tag : copyDatabase - Ininitail database", "Getting ready to Coping Database From the database stored in Asset folder" );
//Open your local db as the input stream
InputStream is = context.getAssets().open(dbNameFK);
String RenameDB2OriginalName = "YAOMasterDB.db";
String outFileName = db_path + RenameDB2OriginalName;
//Open the empty db as the output stream
OutputStream os = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[10000];
Log.i("Tag : copyDatabase - buffer Database", "Coping Database From the database stored in Asset folder" );
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
os.flush();
os.close();
is.close();
this.close();
}
public boolean checkExist() {
SQLiteDatabase checkDB = null;
try {
String myPath = db_path + dbName;
File dbFile = new File( db_path + dbName);
return dbFile.exists();
}
catch (SQLiteException e) {
e.printStackTrace();
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
public void openDataBase() throws SQLException{
//Open the database
String myPath = db_path + dbName;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
public void DeleteDBjet(){
String myPath = db_path + dbName;
File file = new File(myPath);
boolean deleted = file.delete();
}
在您的 SplashActivity
中(发出警告的地方)myHelper.close()
永远不会被调用。
如果您打开数据库或者您正在全局处理它,则需要关闭数据库,这样您就不必一次又一次地打开它。但是当不再在 activity 中使用时,关闭数据库将是一个更好的选择。
改变方法
private void startApp() {
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
startActivity(intent);
}
至此
private void startApp() {
myhelper.close();
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
startActivity(intent);
}
我的应用程序出现以下错误。但是,此错误不会使我的应用程序崩溃。尽管如此,我知道是什么导致了这个错误,但不确定如何修复它。当我更加注意这个错误时,是因为我正在将我的数据库从 Asset 文件夹复制到 /data/ 文件夹。我在整个应用程序中使用相同的代码来确保数据库存在(如果不再次复制)。如果用户误删除了数据库。这就是我使用该代码的原因(我将在错误下方将其传递)。正如我所做的研究,这可能是我的应用程序因内存不足错误而崩溃的原因之一。不确定这是否也会导致内存泄漏。请帮我。就像我之前说的,在出现内存不足错误之前,该应用程序可以正常工作。我想修复从这个错误开始的所有错误。
错误:
01-08 17:22:44.326: E/Database(414): close() was never explicitly called on database '/data/data/com.drakeillusion.yao1/databases/YAOMasterDB.db'
01-08 17:22:44.326: E/Database(414): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
01-08 17:22:44.326: E/Database(414): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810)
01-08 17:22:44.326: E/Database(414): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
01-08 17:22:44.326: E/Database(414): at com.example.yao.YAOMySQLiteHelper.openDataBase(YAOMySQLiteHelper.java:328)
01-08 17:22:44.326: E/Database(414): at com.example.yao.SplashActivity.copydbfromassest(SplashActivity.java:128)
01-08 17:22:44.326: E/Database(414): at com.example.yao.SplashActivity.onCreate(SplashActivity.java:68)
01-08 17:22:44.326: E/Database(414): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-08 17:22:44.326: E/Database(414): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
01-08 17:22:44.326: E/Database(414): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
01-08 17:22:44.326: E/Database(414): at android.app.ActivityThread.access00(ActivityThread.java:125)
01-08 17:22:44.326: E/Database(414): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
01-08 17:22:44.326: E/Database(414): at android.os.Handler.dispatchMessage(Handler.java:99)
01-08 17:22:44.326: E/Database(414): at android.os.Looper.loop(Looper.java:123)
01-08 17:22:44.326: E/Database(414): at android.app.ActivityThread.main(ActivityThread.java:4627)
01-08 17:22:44.326: E/Database(414): at java.lang.reflect.Method.invokeNative(Native Method)
01-08 17:22:44.326: E/Database(414): at java.lang.reflect.Method.invoke(Method.java:521)
01-08 17:22:44.326: E/Database(414): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-08 17:22:44.326: E/Database(414): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-08 17:22:44.326: E/Database(414): at dalvik.system.NativeStart.main(Native Method)
我的活动: 这是我调用的第一个 activity 将数据库从资产文件夹导入到 /data/ 文件夹
public class SplashActivity extends Activity {
String value;
String update = "01";
Boolean mastupdate = false;
private static String DB_PATHNAME = "/data/data/com.example.yao/database/YAOMasterDB.db";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
copydbfromassest();
// Show the splash screen
setContentView(R.layout.activity_splash);
// Find the progress bar
ProgressBar progressBar = (ProgressBar) findViewById(R.id.activity_splash_progress_bar);
// Start your loading
new LoadingTask(progressBar, this).execute("127.0.0.1");
Thread thread = new Thread(){
/////@Override
public void run(){
//TODO Auto-generated nethod stub
//super.run();
try{
sleep(1000);
/////startActivity(new Intent(getApplicationContext(),MainActivity.class));
} catch (InterruptedException e){
//TODO Auto-generated catch block
e.printStackTrace();
//}finally{
// Intent a = new Intent (SplashActivity.this,MainActivity.class);
}
}
};
thread.start();
}
///copy the database from assest folder
private void copydbfromassest() {
// TODO Auto-generated method stub
YAOMySQLiteHelper myhelper = new YAOMySQLiteHelper (this);
try{
//create datbase
myhelper.importIfNotExist();
}catch (IOException e){
throw new Error("Unable to Create the Database ");
}
try{
myhelper.openDataBase();
}catch (SQLException sqle){
throw sqle;
}
}
//// delete the database
private void deletedb() {
// TODO Auto-generated method stub
try{
File f = new File(DB_PATHNAME);
if (f.exists()){
f.delete();
}
}catch (Exception ex){
ex.printStackTrace();
}
}
private void openfilelevel() {
// TODO Auto-generated method stub
FileInputStream fis;
try{
fis = openFileInput("update.ss");
byte [] input = new byte[fis.available()];
while(fis.read(input) != -1){
value = new String (input);
}
fis.close();
if(!value.contentEquals(update)){
mastupdate = true;
createupdatelevel();
}
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
private void createupdatelevel() {
// TODO Auto-generated method stub
String FILENAME = "update.ss";
String JOUR = update;
try{
File file = getBaseContext().getFileStreamPath(FILENAME);
mastupdate = true;
FileOutputStream fos = openFileOutput(FILENAME, getBaseContext().MODE_PRIVATE);
fos.write(JOUR.getBytes());
fos.close();
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
/// text make the file
private void makethefile() {
// TODO Auto-generated method stub
String FILENAME = "Update.ss";
String JOUR = update;
try{
File file = getBaseContext().getFileStreamPath(FILENAME);
if (file.exists()){
Toast.makeText(this, "Exist", Toast.LENGTH_LONG).show();
}else{
mastupdate = true;
FileOutputStream fos = openFileOutput(FILENAME, getBaseContext().MODE_PRIVATE);
fos.write(JOUR.getBytes());
}
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
public void onTaskFinished() {
completeSplash();
}
private void completeSplash(){
startApp();
finish(); // Don't forget to finish this Splash Activity so the user can't return to it!
}
private void startApp() {
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
startActivity(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
这是我的 "DatabaseHelper" 名为 YAOMySQLiteHelper。 YAOMySQLiteHelper 包含很多代码我将通过相应的部分。
public class YAOMySQLiteHelper extends SQLiteOpenHelper {
public static String db_path;
private String dbName;
private String dbNameFK;
private String dbImages;
//private Context context;
private final Context context;
private SQLiteDatabase myDataBase;
private static final String DATABASE_NAMEFK = "YAOMasterDB.jet";
private static final String DATABASE_NAME = "YAOMasterDB.db";
public YAOMySQLiteHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.dbNameFK = DATABASE_NAMEFK;
this.dbName = DATABASE_NAME;
// this.dbImages=DATABASE_IMAGES;
this.context = context;
db_path = "/data/data/" + context.getPackageName() + "/databases/";
}
public void importIfNotExist() throws IOException {
boolean dbExist = checkExist();
if (dbExist) {
Log.i("Tag : ImportIfNotExist", "DB Exist : " + dbExist);
// do nothing - database already exist
} else {
Log.i("Tag : ImportIfNotExist", "DB Not Exist : " + dbExist);
// By calling this method and empty database will be created into
// the default system path
// of your application so we are gonna be able to overwrite that
// database with our database.
this.getReadableDatabase();
try {
copyDatabase();
//Deleteing a file (Database)
// DeleteDBjet();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
/*
* Create a copy of the database from Asset folder to the android emulator
*/
private void copyDatabase() throws IOException {
Log.i("Tag : copyDatabase - Ininitail database", "Getting ready to Coping Database From the database stored in Asset folder" );
//Open your local db as the input stream
InputStream is = context.getAssets().open(dbNameFK);
String RenameDB2OriginalName = "YAOMasterDB.db";
String outFileName = db_path + RenameDB2OriginalName;
//Open the empty db as the output stream
OutputStream os = new FileOutputStream(outFileName);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[10000];
Log.i("Tag : copyDatabase - buffer Database", "Coping Database From the database stored in Asset folder" );
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
os.flush();
os.close();
is.close();
this.close();
}
public boolean checkExist() {
SQLiteDatabase checkDB = null;
try {
String myPath = db_path + dbName;
File dbFile = new File( db_path + dbName);
return dbFile.exists();
}
catch (SQLiteException e) {
e.printStackTrace();
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
public void openDataBase() throws SQLException{
//Open the database
String myPath = db_path + dbName;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
}
@Override
public synchronized void close() {
if(myDataBase != null)
myDataBase.close();
super.close();
}
public void DeleteDBjet(){
String myPath = db_path + dbName;
File file = new File(myPath);
boolean deleted = file.delete();
}
在您的 SplashActivity
中(发出警告的地方)myHelper.close()
永远不会被调用。
如果您打开数据库或者您正在全局处理它,则需要关闭数据库,这样您就不必一次又一次地打开它。但是当不再在 activity 中使用时,关闭数据库将是一个更好的选择。
改变方法
private void startApp() {
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
startActivity(intent);
}
至此
private void startApp() {
myhelper.close();
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
startActivity(intent);
}