2012-02-23 8 views
0

私のアプリケーションにはハイウェイのリストを含むSQLiteデータベースがあります。それらをすべてリストに表示します。まず、道路のデータベースを照会しようとします。クエリが何も返さない場合は、リモートサーバからリストをダウンロードしてデータベースに移入する別のメソッドを呼び出します。その後、すぐにデータベースに再度照会します。Android:SQLiteクエリはリロードなしで0行を返しますか?

これはうまくいくはずです。実際の動作は、最初のクエリは常には何も返しません。新しいリストをダウンロードするとすぐに、データベースにリストが挿入され、再度照会されます。 2番目のクエリは常に正しい結果を返します。奇妙なことは、アプリケーションを終了しなくても操作を繰り返すことができるということです。 adbシェルを使用すると、エミュレータでSQLite3データベースを読み取ることができます。データベースに表示されるデータは、まったく同じです。しかし、アプリケーションはデータが存在しないかのように動作していますか?私が気づいていない動作がいくつかありますか?ここにコードがあります。

RoadsDataSource.java

public class RoadsDataSource { 

    private DataStorage data; 

    private static Context context; 

    public RoadsDataSource() { 
     this.data = new DataStorage(RoadsDataSource.context); 
    } 

    private List<Road> getRoads(Integer state) { 
     List<Road> roads = loadRoadsFromDb(state); 
     if (roads.isEmpty()) { 
      Request api = new Request(RoadsDataSource.context); 
      Roads apiRoads = api.fetchRoads(state); 
      this.data.storeRoads(apiRoads); 
      roads = loadRoadsFromDb(state); 
     } 
     return roads; 
    } 

    private List<Road> loadRoadsFromDb(Integer state) { 
     SQLiteQueryBuilder query = new SQLiteQueryBuilder(); 
     query.setTables(Queries.ROAD_STATE_MATCHES); 
     Cursor results = query.query(
       this.data.getWritableDatabase(), 
       new String[] {Tables.ROADS + "." + Tables.Roads.ID, Tables.ROADS + "." + Tables.Roads.TYPE, Tables.ROADS + "." + Tables.Roads.NUMBER}, 
       Queries.ROADS_BY_STATE, 
       new String[] {state.toString()}, null, null, null 
     ); 

     List<Road> roads = new ArrayList<Road>(); 

     results.moveToFirst(); 
     while (!results.isAfterLast()) { 
      roads.add(new Road(results.getInt(0), results.getString(1), results.getInt(2))); 
      results.moveToNext(); 
     } 
     results.close(); 

     System.out.println(roads.size()); 
     return roads; 
    } 
} 

DataStorage.java

public class DataStorage extends SQLiteOpenHelper { 
    public void storeRoads(Roads roads) { 
     SQLiteDatabase db = this.getWritableDatabase(); 
     for (Road road : roads.getRoads()) { 
      ContentValues roadRow = new ContentValues(); 
      roadRow.put(Tables.Roads.ID, road.getId()); 
      roadRow.put(Tables.Roads.TYPE, road.getType()); 
      roadRow.put(Tables.Roads.NUMBER, road.getNumber()); 
      try { 
       db.insertOrThrow(Tables.ROADS, null, roadRow); 
      } catch (SQLException e) { 
      } 
      ContentValues linkRow = new ContentValues(); 
      linkRow.put(Tables.StatesRoads.STATE_ID, roads.getState()); 
      linkRow.put(Tables.StatesRoads.ROAD_ID, road.getId()); 
      try { 
       db.insertOrThrow(Tables.STATES_ROADS, null, linkRow); 
      } catch (SQLException e) { 
      } 
     } 
    } 
} 
+1

私はアンドロイドのラッパーに精通していません。一般的にsqliteのように、トランザクションが完了していない場合、その動作が期待されます。私はまた、空のキャッチがコードレビューに合格することを許可しません。あなたは奇妙な行動を求めています。 :) –

+0

空のキャッチについては、私は開発の初期段階にあります。この時点で、私はただの機能を手に入れようとしています。そして、私は戻って例外のようなものに対処します。 – Jonah

+1

ちょっと質問がありますが、loadRoadsではgetReadableDatabase()を使用してgetWriteableDatabase呼び出しでオープンされたハンドルを閉じるべきではありませんか? –

答えて

1

SQLiteDatabase db = this.getWritableDatabase(); 

置き換え以上のようになります。ハンドル - 一般的に私はすべてのdb操作をSQLiteOpenHelperサブクラス内で行い、dbへの参照を保持し、アトミックに開き、閉じます。

2

のMo Kargasは正しいです。あなたのデシベルヘルパーは、これはあなたの問題を解決することがありhttp://code.google.com/p/android-notes/source/browse/trunk/src/com/bitsetters/android/notes/DBHelper.java?r=10

これはしかし、データベースを閉じていないと私は過去に大きな問題を持っていたこの

SQLiteDatabase db; 
try { 
    db = dbHelper.getWritableDatabase(); 
} catch (SQLiteException e) { 
    db = dbHelper.getReadableDatabase(); 
} 
関連する問題