2017-02-13 5 views
2

私は、その機能の一部がサーバーからJSON形式の巨大なアイテムのリストを取得し、ローカルに保存するアプリケーションを開発していますSQLiteデータベース。 JSONファイルが巨大なので、Gsonライブラリを使ってフェッチを実行しています。そうでないと、RAMが不足しているためアプリケーションがクラッシュします。したがって、私の唯一の選択肢はファイルをストリームとして取得することです。JSONストリームをAndroid上のローカルデータベースに保存するパフォーマンスを向上させる

JSONファイルの構造は次のようになります。ストリームを処理する

{ 
    "items": [ 
    { 
     "itemID": "id1", 
     "itemName": "name1" 
    }, 
    { 
     "itemID": "id2", 
     "itemName": "name2" 
    } 
    ] 
} 

私のJavaコードのようになります。機能storeItemData(String id, String name)はこのようになります

JsonReader reader = new JsonReader(url_buffered_reader); 
reader.beginObject(); 

String itemId = null; 
String itemName = null; 

while (reader.hasNext()) { 
    if (reader.nextName().equals("items")) { 
     reader.beginArray(); 
     while (reader.hasNext()) { 
      reader.beginObject(); 
      while (reader.hasNext()) { 
       String name = reader.nextName(); 
       switch (name) { 
        case "itemID": 
         itemId = reader.nextString().trim(); 
         break; 
        case "itemName": 
         itemName = reader.nextString().trim(); 
         break; 
        default: 
         reader.skipValue(); 
         break; 
       } 
      } 
      reader.endObject(); 

      storeItemData(itemId, itemName); 
     } 
     reader.endArray(); 
    } 
} 

(それはクラスでありますそれはSQLiteOpenHelperを拡張します):

public void storeItemData(String id, String name) { 
    SQLiteDatabase db = this.getWritableDatabase(); 

    ContentValues values = new ContentValues(); 
    values.put("itemID", id); 
    values.put("itemName", name); 

    long newRowId = db.insertWithOnConflict(
      "items", 
      null, 
      values, SQLiteDatabase.CONFLICT_REPLACE); 
} 

コードが動作しています良い。データは正常にダウンロードされ、保存されます。問題は、パフォーマンスが良くないことです。パフォーマンスを向上させるために、データを保存する効率的な方法はありますか?

答えて

1

レコードをデータベースに挿入する際のオーバーヘッドがあります。データベースがボトルネックであると仮定すると、挿入をトランザクションにラップすることで書き込みパフォーマンスを向上させることができます。

  1. storeItemDataのうちSQLiteDatabase db = this.getWritableDatabase();を移動します。
  2. 挿入を開始する前にdb.beginTransaction();に電話してください。
  3. 挿入が完了した後にdb.setTransactionSuccessful();と、その後db.endTransaction();と電話してください。
  4. 挿入が原因で発生する可能性のあるエラーを正常に処理できるように、例外を必ず捕捉してください。
+0

ありがとうございました!私は実際に最初の作業をしていますが、関数の中に移動して、不必要なコードを大量にコピー・ペーストする必要はありません。 'db.beginTransaction();'と 'db.endTransaction();'に関して、私はJSONループの前後に置くべきでしょうか?私が理解しているところでは、db.endTransaction();に達すると、すべてのレコードを1つずつ処理するのではなく、すべてをコミットします。 – jackgu1988

+1

ループの前後で、すべての 'storeItemData'呼び出しを間に実行している限り、ループは正常に動作するはずです。そして、そうです、あなたの挿入物のすべては 'endTransaction'に達するとコミットします。 – Tim

+0

これはまさに私が望んでいたものです!私はネットワークモニタで接続が安定しているのを見ることもできますが、データを保存する前に毎秒停止しています。 – jackgu1988

関連する問題