导入数据库后从未在数据库上显式调用 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);
}