2016-03-18 37 views
0

我的應用程序預裝了三個數據庫。其中一個很大,293,092行大部分都是長句子。我的問題是,即使在工作線程中查詢(rawQuery)大的UI,UI也會凍結1秒。即使在另一個線程中執行,查詢大型SQLite數據庫也會導致UI凍結

這裏是我的查詢語句:

SELECT verse 
FROM Translations 
WHERE translatorId = ? 
AND chapterNbr = ? 
AND verseNbr BETWEEN ? AND ? 
ORDER BY chapterNbr , verseNbr 

這裏的問題是,即使我刻意的只是1行(1個結果)查詢時,用戶界面仍然凍結。

請幫忙。非常感謝你。

這是我很長碼:當我使用DB.user.db代替DB.trans.db上述

static void setVerseAdapter(final int[][] refs) { 

    surahThread = new Thread(new Runnable() { 
     @Override 
     public void run() {   
       Cursor cursor = Translations.getTranslators(); 
       final int[] translationIds = new int[cursor.getCount()]; 
       while (cursor.moveToNext()) { 
        translationIds[cursor.getPosition()] = cursor.getInt(0); 
       } 

       adapterVerses = new AdapterVerses 
         (context, getVersesArray(refs), Translations.getTranslationsArray(translationIds, refs)); // this one is the problem, the getTranslationsArray    

      // remaining code in this method is irrelevant ... 
    }); 

    surahThread.start(); 
} 

static Cursor[][] getTranslationsArray(int[] translationIds, int[]... refs) { 

    if (!Settings.showTranslation) 
     return new Cursor[][]{{}}; 

    Cursor[][] translations = new Cursor[refs.length][]; 

    for (int i = 0; i < refs.length; i++) { 
     int start = refs[i][0]; 
     int end = refs[i][1]; 
     int surahNbr = refs[i][2]; 
     translations[i] = getTranslations(translationIds, start, end, surahNbr); 
    } 

    return translations; 
} 


static Cursor[] getTranslations(int[] translatorIds, int start, int end, int surahNbr) { 

    Cursor[] translations = new Cursor[translatorIds.length]; 

    for (int i = 0; i < translatorIds.length; i++) { 
     translations[i] = readTrans(
       "SELECT verse " + 
         "FROM Translations " + 
         "WHERE translatorId = ? " + 
         "AND surahNbr = ? " + 
         "AND verseNbr BETWEEN ? AND ? " + 
         "ORDER BY surahNbr, verseNbr", 
       translatorIds[i], surahNbr + 1, start, end 
     ); 
    } 

    return translations; 
} 

static Cursor readTrans(String query, Object... args) { 
    SQLiteDatabase transDb = transExists ? DB.trans.db : DB.user.db; // using user.db results to no freezing 
    return transDb.rawQuery(replaceArgs(query, args), null); 
} 

一切工作正常。他們之間的差異是他們的大小。第一個只是〜4MB,第二個(有問題的)約爲65MB解包時。

謝謝。

+2

請提供[mcve]。這將包括查詢數據庫的代碼以及使用從查詢中返回的「Cursor」的代碼。 – CommonsWare

+0

我已更新我的問題。謝謝。 –

+3

你的代碼是......莫名其妙。你們也在迅速接連地提出許多疑問,這將導致總體表現不佳。特別是關於線程,確保你在*後臺線程中*時從*數據庫*中獲得* Cursor *。像query()和rawQuery()這樣的方法實際上不會執行查詢。他們設置了'Cursors',但是直到你真的用'Cursor'做了一些事情(懶惰的評估),查詢才完成。調用'getCount()',如果沒有別的。 – CommonsWare

回答

0

您可以使用IntentService從活動遠運行的查詢,然後通過發回的查詢結果intent.putExtra的活動..

0

我解決它通過簡單的索引違規表(是的,我沒有索引它,因爲我是一個總noob)。查詢花了600毫秒的非索引和僅5毫秒的索引。

(即我仍然無法把握的是它爲什麼凍結我的UI開始用好奇的一部分嗎?是不是應該質疑在我剛剛創建的後臺線程做?)

0

的問題是你正在等待數據被查詢。將數據庫操作轉移到另一個線程無關緊要;當UI線程等待另一個線程完成時,它仍然阻塞。

您應該只查詢您實際需要顯示的數據,並確保數據庫操作已正確優化。 但是,如果查詢仍然太慢,避免凍結UI的唯一方法是顯示沒有數據的用戶界面。

相關問題