.DatabaseObjectNotClosedException

时间:2014-01-31 09:12:45

标签: java android

我的logcat显示上述错误。

然而,在Databasehelper类的所有方法中,我都为db对象调用了close()方法。

以下是db helper类的一些代码。

    public MyDatabaseAdapter(Context context,String databaseName){  
            super(context,databaseName,null,1);
        this.mycontext=context;
        try{
            Log.v("Path",DB_PATH);
        DB_NAME=databaseName;   
        Log.v("name",DB_NAME);
        openDataBase();         
        }catch(Exception e)
        {
            Log.e("gezaaako",e.toString());
        }
    }

    public SQLiteDatabase openDataBase()  throws SQLException
    {
        String myPath=DB_PATH+DB_NAME;
        Log.e("CheckPath",myPath);
        if (myDataBase==null)
        {
            try {
                createdatabase();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }   

        myDataBase=SQLiteDatabase.openDatabase(myPath,null,SQLiteDatabase.OPEN_READWRITE);
        }
        return myDataBase;
    }
    public synchronized void close()
    {
        if(myDataBase!=null){
        myDataBase.close();
        }
        super.close();
    }
public long AddMeter(Meters meter){
    SQLiteDatabase db=this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(SERIALNUMBER, meter.getSerialNumber().toString());
    values.put(METERNUMBER, meter.getMeterNumber().toString());
    values.put(DATEADDED, getDateTime());
    long meterid=db.insert(TABLE_METERS, null, values);
    db.close();
    return meterid;


}

在AddMeter方法中,我明确地调用了close方法。

这是一个使用游标的方法

public List<TenantMeterID> GetTenantMeterIds()
{
    List<TenantMeterID> meterlist = new ArrayList<TenantMeterID>();
    String selectQuery = " SELECT  * FROM " +View_Tenant_Meter_id;
    Log.e("LOG", selectQuery);      
    SQLiteDatabase db = this.getReadableDatabase();
    Cursor c = db.rawQuery(selectQuery, null);
    if(c.moveToFirst()){
        do{
            TenantMeterID t = new TenantMeterID();
            t.set_id(Integer.parseInt(c.getString(c.getColumnIndex(KEY_ID))));
            t.setFullName(c.getString(c.getColumnIndex(TENANT)));

            meterlist.add(t);
        } while(c.moveToNext());

    }
    c.close();
    db.close();
    return meterlist;
}

同样,我认为,我明确地关闭了游标和数据库对象。

这里是logcat

01-31 10:42:53.843: D/dalvikvm(334): GC_CONCURRENT freed 179K, 50% free 2825K/5639K, external 734K/1032K, paused 4ms+8ms
01-31 10:42:53.903: E/Database(334): close() was never explicitly called on database 'data/data/com.example.metermanager/databases/meterapp.sqlite' 
01-31 10:42:53.903: E/Database(334): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
01-31 10:42:53.903: E/Database(334):    at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1847)
01-31 10:42:53.903: E/Database(334):    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:820)
01-31 10:42:53.903: E/Database(334):    at meter.manager.helper.MyDatabaseAdapter.openDataBase(MyDatabaseAdapter.java:194)
01-31 10:42:53.903: E/Database(334):    at meter.manager.helper.MyDatabaseAdapter.<init>(MyDatabaseAdapter.java:105)
01-31 10:42:53.903: E/Database(334):    at com.example.metermanager.allTenants.<init>(allTenants.java:32)
01-31 10:42:53.903: E/Database(334):    at com.example.metermanager.GetTeantList.onCreate(GetTeantList.java:21)
01-31 10:42:53.903: E/Database(334):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-31 10:42:53.903: E/Database(334):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
01-31 10:42:53.903: E/Database(334):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
01-31 10:42:53.903: E/Database(334):    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
01-31 10:42:53.903: E/Database(334):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
01-31 10:42:53.903: E/Database(334):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-31 10:42:53.903: E/Database(334):    at android.os.Looper.loop(Looper.java:123)
01-31 10:42:53.903: E/Database(334):    at android.app.ActivityThread.main(ActivityThread.java:3683)
01-31 10:42:53.903: E/Database(334):    at java.lang.reflect.Method.invokeNative(Native Method)
01-31 10:42:53.903: E/Database(334):    at java.lang.reflect.Method.invoke(Method.java:507)
01-31 10:42:53.903: E/Database(334):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-31 10:42:53.903: E/Database(334):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-31 10:42:53.903: E/Database(334):    at dalvik.system.NativeStart.main(Native Method)

似乎建议我必须在我使用db helper类的类中显式关闭db对象。

是这样的吗?

我一直在使用,只需在课堂上调用它。 e.g

public allTenants(Context context1) {       
        this.context=context1;
        MyDatabaseAdapter db= new  MyDatabaseAdapter( context1,DB_NAME);
        readings=db.GetAllTenants();
    }

在上面的例子中,怎么说显式调用close方法?

读数= db.GetAllTenants();?

如果我的帖子包含不相关的部分,我很抱歉!

罗纳德

2 个答案:

答案 0 :(得分:0)

 public class DBAdapter 
 {
       private static final String DATABASE_NAME = "GSDATA.db";
       private static final int DATABASE_VERSION = 2;
            private static final String CREATE_COVERPHOTO_TABLE =
               "CREATE TABLE IF  NOT  EXISTS COVERPHOTO (path Text,date DATE);";

       private final Context context; 
       public String group;
       private DatabaseHelper DBHelper;
       private static SQLiteDatabase db;






        public DBAdapter(Context ctx)
        {
            this.context = ctx;
            DBHelper = new DatabaseHelper(context);
        }
        private  class DatabaseHelper extends SQLiteOpenHelper 
        {
            DatabaseHelper(Context context) 
            {
                super(context, DATABASE_NAME, null, DATABASE_VERSION);
            }
            @Override
            public void onCreate(SQLiteDatabase db) 
            {
                db.execSQL(CREATE_COVERPHOTO_TABLE);

                System.out.println("The Database is Created Here :");
            }

            @Override
            public void onUpgrade(SQLiteDatabase db, int 
                 oldVersion, int   newVersion) 
            {
                //db.execSQL("DROP TABLE IF EXISTS calSimpleNote");
                onCreate(db);
            }
        } //database helper class complete  

        //---opens the database---
        public DBAdapter open() throws SQLException 
        {
            db = DBHelper.getWritableDatabase();
            return this;
        }
        //---closes the database---    
        public void close() 
        {
            DBHelper.close();
            db.close();
        }

   // and use below  code where you close or open data base

   db.open()
  // your code
  db.close();

答案 1 :(得分:0)

Cursor c = db.rawQuery(selectQuery, null);
    if(c.moveToFirst()){
        do{
            TenantMeterID t = new TenantMeterID();
            t.set_id(Integer.parseInt(c.getString(c.getColumnIndex(KEY_ID))));
            t.setFullName(c.getString(c.getColumnIndex(TENANT)));

            meterlist.add(t);
        } while(c.moveToNext());

    }
    c.close();
    //db.close();
    return meterlist;

在MainActivity中实现onDestory()或onPause() 将数据库引用声明为公共变量

  

SQLiteDatabase db = this.getReadableDatabase();

  @Override
  protected void onPause() { or  protected void onDestroy()
     super.onPause();
    db.close();

  }