简体   繁体   中英

DatabaseObjectNotClosedException after activity start

I'm newbie with android development and I m developing a sandbox project. I'm meeting a strange error with SQLite, when activity start I wont have any error, the data are well retrieve, but when I start a new activity I have this error(on the current activity, not the new started):

 E/Cursor﹕ Finalizing a Cursor that has not been deactivated or closed. database = /data/data/be.lud.planetsdb/databases/planetManager2, table = Planetes, query = SELECT * FROM Planetes WHERE _id = 2
        android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
                at android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:210)
                at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53)
                at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345)
                at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1229)
                at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1184)
                at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1301)
                at be.lud.planetsdb.PlanetAdapter.getPlanetById(PlanetAdapter.java:102)
                at be.lud.planetsdb.Planet_Activity.onCreate(Plane

t_Activity.java:44)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
            at android.app.ActivityThread.access$2300(ActivityThread.java:125)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:123)
            at android.app.ActivityThread.main(ActivityThread.java:4627)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:521)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
            at dalvik.system.NativeStart.main(Native Method)

Here's my adapter class

    public class PlanetAdapter {

    public static final String DB_NAME = "planetManager2";
    public static final String TABLE_NATURE = "Natures";
    public static final String TABLE_PLANETES = "Planetes";
    public static final String COLONNE_ID = "_id";
    public static final String COLONNE_NATURE_ID = "natureId";
    public static final String COLONNE_NOM = "name";
    public static final String COLONNE_TEMP = "temperature";
    public static final String COLONNE_ORDRE = "orderInd";
    public static final String COLONNE_RAYON = "rayon";
    public static final String COLONNE_VIABLE = "isLivable";
    public static final int VERSION_NUMBER = 1;

    private PlanetDbHelper myhelper;
    private Context context;
    private SQLiteDatabase db;

    public PlanetAdapter(Context ctx){
        this.context = ctx;
    }

    public long insert(Planet newPlanet){
        ContentValues values = new ContentValues();
        values.put(COLONNE_NATURE_ID, newPlanet.getNatureId());
        values.put(COLONNE_NOM, newPlanet.getName());
        values.put(COLONNE_TEMP, newPlanet.getTemperature());
        values.put(COLONNE_ORDRE, newPlanet.getOrder());
        values.put(COLONNE_RAYON, newPlanet.getRayon());
        values.put(COLONNE_VIABLE, newPlanet.isLivable());

        return db.insert(TABLE_PLANETES, null, values);

    }

    public void update(Planet upPlanet){

        ContentValues values = new ContentValues();
        values.put(COLONNE_NOM, upPlanet.getName());
        values.put(COLONNE_TEMP, upPlanet.getTemperature());
        values.put(COLONNE_ORDRE, upPlanet.getOrder());
        values.put(COLONNE_RAYON, upPlanet.getRayon());
        values.put(COLONNE_VIABLE, upPlanet.isLivable());

        db.update(TABLE_PLANETES, values, upPlanet.getId() + "=" + COLONNE_ID, null);


    }

    private Planet cursorToPlanet(Cursor c){
        Planet p = new Planet();
        //Log.i("id", String.valueOf(c.getInt(c.getColumnIndex(COLONNE_ID))));
        p.setId(c.getInt(c.getColumnIndex(COLONNE_ID)));
        p.setName(c.getString(c.getColumnIndex(COLONNE_NOM)));
        p.setTemperature(c.getInt(c.getColumnIndex(COLONNE_TEMP)));
        p.setNatureId(c.getInt(c.getColumnIndex(COLONNE_NATURE_ID)));
        p.setOrder(c.getInt(c.getColumnIndex(COLONNE_ORDRE)));
        p.setRayon(c.getInt(c.getColumnIndex(COLONNE_RAYON)));
        p.setLivable(c.getInt(c.getColumnIndex(COLONNE_VIABLE)));

        //Log.i("id p ", String.valueOf(p.getId()));

        return p;
    }

    public Cursor getPlanetCursorByUd(int id){
        openReadable();
        String[] colQ = new String[]{COLONNE_ID, COLONNE_NOM, COLONNE_TEMP, COLONNE_NATURE_ID, COLONNE_ORDRE, COLONNE_RAYON, COLONNE_VIABLE};
        Cursor c = db.query(TABLE_PLANETES, colQ , COLONNE_ID + " = " + id, null, null, null, null, null);

        if(c.getCount() != 0){
            c.moveToFirst();
            close();
            return c;

        }else {
            close();
            return null;
        }
    }

    public Planet getPlanetById(int id){
        openReadable();
        String[] colQ = new String[]{COLONNE_ID, COLONNE_NOM, COLONNE_TEMP, COLONNE_NATURE_ID, COLONNE_ORDRE, COLONNE_RAYON, COLONNE_VIABLE};
        Cursor c = db.query(TABLE_PLANETES, null , COLONNE_ID + " = " + id, null, null, null, null, null);


        if(c.getCount() != 0){
            c.moveToFirst();

            Planet p = cursorToPlanet(c);
            close();
            return p;

        }else {
            close();
            return null;
        }


    }

    public List<Planet> getAllPlanet(){
        List<Planet> allPlanets = new ArrayList();
        openReadable();
        //String[] colQ = new String[]{COLONNE_ID, COLONNE_NOM, COLONNE_TEMP, COLONNE_NATURE_ID, COLONNE_ORDRE, COLONNE_RAYON, COLONNE_VIABLE};
        Cursor c = db.query(TABLE_PLANETES, null , null, null, null, null, null, null);

        if(c.moveToFirst()){
            for (int i = 0; i < c.getCount(); i++, c.moveToNext()){
                allPlanets.add(cursorToPlanet(c));
            }
            close();
            return allPlanets;

        }else {
            close();
            return null;
        }

    }

    public Map<Integer, String> getAllNatures(){
        openReadable();
        Map<Integer, String> dicNature = new Hashtable() ;

        String[] colQ = new String[]{COLONNE_ID, COLONNE_NOM};
        Cursor c = db.query(TABLE_NATURE, colQ , null, null, null, null, null, null);


        c.moveToFirst();

        if(c.getCount() != 0){
            for (int i = 0; i < c.getCount(); i++, c.moveToNext()){
                dicNature.put(c.getInt(c.getColumnIndex(COLONNE_ID)), c.getString(c.getColumnIndex(COLONNE_NOM))) ;
            }
            close();
            return dicNature;

        }else {
            close();
            return null;
        }

    }


    public PlanetAdapter openWritable(){
        myhelper = new PlanetDbHelper(context, DB_NAME, null, VERSION_NUMBER );

        db = myhelper.getWritableDatabase();
        return this;
    }

    public PlanetAdapter openReadable(){
        myhelper = new PlanetDbHelper(context, DB_NAME, null, VERSION_NUMBER );
        db = myhelper.getReadableDatabase();
        return this;
    }

    public void close(){
        myhelper.close();
        db.close();

    }
}

here's what I do on the onCreate()

 PlanetAdapter adp = new PlanetAdapter(getApplicationContext());

  try{
    myPlanet = adp.getPlanetById(planetId);

   }catch (Exception e){
     e.getMessage();
    }

Any idea what I'm doing wrong?

if(database.isOpen()) database.close();
根据您的要求在onStop()onPause()添加此代码。

Use This two method for open and close database....it might be helpful to you..

public Image_Sql Open() throws SQLException {

    ourHelper = new DBHelper(ourContext);
    ourDatabase = ourHelper.getWritableDatabase();

    return this;

}

public void Close() {
    ourDatabase.close();
}

this method write in your database file....and when you fetch the data then open the database...and after close it..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM