Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android SQLite泄漏_Android_Sqlite - Fatal编程技术网

Android SQLite泄漏

Android SQLite泄漏,android,sqlite,Android,Sqlite,我发现sql处理程序有问题 A SQLiteConnection object for database '/data/data/.../databases/queueManager' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed. @Override

我发现sql处理程序有问题

A SQLiteConnection object for database '/data/data/.../databases/queueManager' was leaked!  Please fix your application to end transactions in progress properly and to close the database when it is no longer needed.
 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }
取自Androidhive教程,并根据我的使用进行了定制

 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }
这张桌子看起来像

+ ----------------------------------------------------------- +
: DATABASE_ID : DATABASE_QID : DATABASE_QUEUE : DATABASE_DATE :
+ ----------------------------------------------------------- +
 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }
代码

   DBQueue searchDBqid(int id) {
       SQLiteDatabase db = this.getReadableDatabase();

        String selectQuery = "SELECT  * FROM " + TABLE_QUEUE + " WHERE " + DATABASE_QID + " = " + id; 

           Cursor cursornum = db.rawQuery(selectQuery, null);
           int dk = cursornum.getCount();
           cursornum.close();

           if (dk >0) {
               Cursor cursor = db.query(TABLE_QUEUE, new String[] { DATABASE_ID,
                       DATABASE_QID, DATABASE_QUEUE, DATABASE_DATE }, DATABASE_QID + "=?",
                       new String[] { String.valueOf(id) }, null, null, null, null);

               if (cursor != null) cursor.moveToFirst();

               DBQueue dbqueue = new DBQueue(Integer.parseInt(cursor.getString(0)),
                       cursor.getString(1), cursor.getString(2), cursor.getString(3));
               return dbqueue;
           }

       db.close();
       return null;
   }

   DBQueue getDBQueue(int id) {
       SQLiteDatabase db = this.getReadableDatabase();

       Cursor cursor = db.query(TABLE_QUEUE, new String[] { DATABASE_ID,
               DATABASE_QID, DATABASE_QUEUE }, DATABASE_ID + "=?",
               new String[] { String.valueOf(id) }, null, null, null, null);
       if (cursor != null)
           cursor.moveToFirst();

       DBQueue dbqueue = new DBQueue(Integer.parseInt(cursor.getString(0)),
               cursor.getString(1), cursor.getString(2), cursor.getString(3));
       return dbqueue;
   }


   public String getAllqid() {
       Time today = new Time(Time.getCurrentTimezone());
       today.setToNow();

       String selectQuery = "SELECT  * FROM " + TABLE_QUEUE + " WHERE " + DATABASE_DATE + " = '" + today.format("%d %m %Y") + "'";

       SQLiteDatabase db = this.getWritableDatabase();
       Cursor cursor = db.rawQuery(selectQuery, null);

       StringBuilder sb = new StringBuilder();       
       if (cursor.moveToFirst()) {
           do {
               if (sb.length() > 0) sb.append(',');
               sb.append(cursor.getString(1));
           } while (cursor.moveToNext());
       }

       String result = sb.toString();
       return result;
   }
   public void deleteDatedDBQueue() {
        Time today = new Time(Time.getCurrentTimezone());
        today.setToNow();
        String selectQuery = "SELECT  * FROM " + TABLE_QUEUE + " WHERE " + DATABASE_DATE + " != '" + today.format("%d %m %Y") + "'"; ;

        SQLiteDatabase db = this.getWritableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        if (cursor.moveToFirst()) {
            do {
                db.delete(TABLE_QUEUE, DATABASE_ID + " = ?",
                       new String[] { String.valueOf(Integer.parseInt(cursor.getString(0))) });
            } while (cursor.moveToNext());
        }
        db.close();
    }
   public int getDBQueueCount() {
       String countQuery = "SELECT  * FROM " + TABLE_QUEUE;
       SQLiteDatabase db = this.getReadableDatabase();
       Cursor cursor = db.rawQuery(countQuery, null);
       cursor.close();

       return cursor.getCount();
   }
}
 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }
有人能告诉我怎么修补这个漏洞吗

 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }

完整代码:

如果在某些情况下忘记关闭光标,请确保在完成操作时始终关闭光标

 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }
例如,第二个查询没有关闭光标,为了清楚起见,我必须关闭它

 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }
此外,在
getDBQueue
getAllqid
getDBQueueCount
中完成后,您不会关闭
SQLiteDatabase
,如果您更改设计使
SQLiteOpenHelper
成为一个单例,则无需关闭
SQLiteDatabase
,并避免泄漏

 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }
DBQueue searchDBqid(int-id){
SQLiteDatabase db=this.getReadableDatabase();
String selectQuery=“SELECT*FROM”+表\队列+”,其中“+数据库\队列+”=“+id;
游标cursornum=db.rawQuery(selectQuery,null);
int dk=cursornum.getCount();
cursornum.close();
如果(dk>0){
//TODO:关闭此光标!
Cursor Cursor=db.query(表队列,新字符串[]{DATABASE\u ID,
数据库_QID,数据库_队列,数据库_日期},数据库_QID+“=?”,
新字符串[]{String.valueOf(id)},null,null,null,null);
if(cursor!=null)cursor.moveToFirst();
DBQueue DBQueue=new DBQueue(Integer.parseInt(cursor.getString(0)),
cursor.getString(1)、cursor.getString(2)、cursor.getString(3));
返回dbqueue;
}
db.close();
返回null;
}

完成后,每个
光标都应关闭。传统的方法是:

 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }
Cursor Cursor=db.query(…);
试一试{
//在此处从光标读取数据
}最后{
cursor.close();
}
但现在,随着时间的推移,它可以更加简洁:

 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }
try(游标=db.query(…){
//在此处从光标读取数据
}

第一次打开数据库,最后一次放入此代码

 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }

每次打开数据库(可读或可写)时,使用内存资源的游标必须在每个数据库函数中使用结束后使用“.close();”解除分配 例如:

 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }

等等

我还认为这是因为数据库在一些方法中没有关闭,这可能意味着当他的开放助手超出范围时,它会泄漏,因此在我的回答中,我建议将开放助手设置为单例,以避免在他尝试跨多个线程使用它时只会变得更糟的打开/关闭问题:)是的,数据库连接应该始终是单例连接。好的,我每次使用游标时都使用这个方法。并添加了少量db.close();我认为它解决了这个问题。谢谢在使用游标之前,您可能希望检查游标是否为null,例如,
if(cursor!=null)cursor.close()@99,这对于数据库查询不是必需的。它永远不会返回空游标。(不过内容提供者不同。)你能帮我解决这个问题吗
 @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
         mdb.close();   
         super.onDestroy();
        }