2011-08-12 77 views
0

我在我的android应用程序中有一个SQLite查询,当它执行时间太长时,似乎会崩溃。它崩溃与NullPointerException并告诉我的行号...Android SQLite查询崩溃时间过长?

当我把断点周围,看到它总是充满变量,应用程序不会崩溃,并做它应该的。

所以,除了有一个幻影空指针,看来问题是,断点实际上放慢速度,给查询时间完成。没有断点,它总是崩溃而不失败。

这里的其他人似乎也有类似的问题,我已经读了一些关于SQLite花费大量时间来完成任务的东西,但是这个表只应该有一些条目(我是一个测试应该只有三个条目,4列)

有关如何使它不会崩溃的建议?也许把一个线程等待内部查询的方法?

public void fetchItemsToRemove() throws SQLException{ 
    Cursor mCursor = 
      mapDb.query(myMain_TABLE, new String[] {myOtherId, myCustomID, myDATE}, null, null, null, null, null); 

    if(mCursor.moveToFirst()) 
    { 
      do 
      { 
       /*taking "dates" that were stored as plain text strings, and converting them to 
       *Date objects in a particular format for comparison*/ 

       String DateCompareOld = mCursor.getString(mCursor.getColumnIndex(myDATE)); 
       String DateCompareCurrent = ""; 
       Date newDate = new Date(); 
       DateCompareCurrent = newDate.toString(); 

       try { 
        DateCompareOld = (String)DateCompareOld.subSequence(0, 10); 
        DateCompareCurrent = (String)DateCompareCurrent.subSequence(0, 10); 
        SimpleDateFormat dateType = new SimpleDateFormat("EEE MMM dd"); 
        Date convertDate = dateType.parse(DateCompareOld); 

        newDate = dateType.parse(DateCompareCurrent); 

        if(convertDate.compareTo(newDate) < 0) 
        { 
         //remove unlim id 
         mapDb.delete(myMain_TABLE, myDATE + "=" + mCursor.getString(mCursor.getColumnIndex(myDATE)), null); 

        } 

       } catch (ParseException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      }while(mCursor.moveToNext()); 
      mCursor.close(); 
    } 
    else 
    { 
     mCursor.close();  
    } 


} 

现在“行342”在这里与NullPointerException异常崩溃是DateCompareOld = (String)DateCompareOld.subSequence(0, 10);那里得到的字符串的序列。如果它到达并且为空,这意味着该字符串从未填充在​​

就好像查询刚刚被跳过,因为它花了太长时间。请注意这是在一个while循环中,并且我已经完成了测试以确保mCursor永远不会超出界限。

+0

发布包含其崩溃行的代码。 –

+0

你的SQLite连接有一个超时设置吗?如果是,它是否始终在执行开始后的某个/某个/某个时间发生,或者持续一段时间? – jefflunt

+0

“我不觉得代码是相关的......” - 代码和logcat输出总是相关的。我们不介意这里的读者。 ;) – Squonk

回答

2

您正在从数据库表中删除事物,同时遍历该表的查询结果。听起来有点危险。

尝试在循环内建立要删除的内容的列表,然后在循环结束后单次删除它们。

此外,将整个事情包装在数据库事务中。当您在循环中修改数据库时,这会对性能产生巨大影响。

编辑:交易简单的解释:

的事务让你一堆的数据库查询的合并/修改成一个单一的原子操作,其成功或失败。它主要是一种安全机制,所以如果事情中途出错,你的数据库不会陷入一种不一致的状态,但这也意味着任何修改都会一次性提交给数据库的文件存储,而不是一次一个,速度要快得多。

你在你的函数开始启动事务:

public void fetchItemsToRemove() throws SQLException{ 
    db.beginTransaction(); 
    Cursor mCursor = .... 

将它设置为成功的,如果整体功能完成无误。这可能意味着您想要删除内部的try/catch,并且有一个外部的try/catch包围该循环。然后,在try{ }结束时,你可以假设什么也没有了问题,所以你拨打:

db.setTransactionSuccessful(); 

然后,在finally条款,以确保您始终关闭交易无论是成功或失败:

db.endTransaction(); 
+0

“在数据库事务中包装整个事物”?你能否详细说明这一点,我不熟悉那个术语 – CQM

+0

@RD补充说明了交易。 –

+0

谢谢,我的新问题是,我不能做一个WHERE语句,有效地得到我在找什么。我需要一个where语句将这些纯文本日期取出,如果它们“小于”今天的日期。 SQLite没有日期函数,使得单个语句的比较不那么直观,建议? – CQM