2016-03-18 15 views
0

私のアプリは3つのデータベースがあらかじめ同梱されています。 1つは大きく、大部分は長い文を含む293,092行です。私の問題は、私がクエリ(rawQuery)ワーカースレッドでも大きなもの、UIはおそらく1秒間フリーズするたびにです。大規模なSQLite DBをクエリすると、別のスレッドで実行されてもUIがフリーズする

はここに私のクエリ文です:私は意図的にちょうど1行(1つの結果)を照会しても

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

ここでの問題があり、UIがまだフリーズします。

助けてください。どうもありがとうございました。私が代わりにDB.trans.dbのDB.user.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であり、2番目のもの(問題のあるもの)は解凍時に約65MBです。

ありがとうございます。

+2

[mcve]を入力してください。これには、データベースを照会するコードと、クエリから返される 'Cursor'を使用するコードが含まれます。 – CommonsWare

+0

私は自分の質問を更新しました。ありがとうございました。 –

+3

あなたのコードは...困惑しています。あなたはまた、急速に連続してたくさんのクエリを作成しています。それは一般的にパフォーマンスが低下する原因になります。特にスレッディングに関しては、あなたがバックグラウンドスレッド*中にある間に*データベースから戻ってくる*すべての 'Cursor 'で何かをしていることを確認してください。 'query()'や 'rawQuery()'のようなメソッドは実際にはクエリを実行しません。彼らは 'Cursor 'を設定しますが、' Cursor'(遅延評価)を使って実際に何かを行うまでクエリは実行されません。他のものがなければ、 'getCount()'を呼び出します。 – CommonsWare

答えて

0

あなたが活動にintent.putExtraを経由して、クエリの結果を送り返し、その後、遠く活動からのクエリを実行するためにIntentServiceを使用することができます。..

0

私は単に問題のインデックスを作成することによって、それを解決テーブル(はい、私はインデックスを作成していないので、私は全然ノブです)。照会には索引付けされていない場合は600ミリ秒、索引付けの場合はわずか5ミリ秒かかりました。

(それがそもそも私のUIをフリーズしない理由私はまだ把握できない好奇心の部分はありますか?私が作成したバックグラウンドスレッドで実行されることになって照会していませんか?)

0

問題がありますデータが照会されるのを待っていることを示します。データベース操作を別のスレッドに移動するかどうかは関係ありません。 UIスレッドは他のスレッドが終了するまで待機しますが、それでもブロックされます。

実際に表示する必要があるデータのみを照会し、データベース操作が適切に最適化されていることを確認する必要があります。 しかし、クエリがまだ遅すぎる場合は、UIをフリーズしないようにする唯一の方法は、データなしでUIを表示することです。

関連する問題