2011-08-12 126 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