私のアプリケーションにはハイウェイのリストを含む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) {
}
}
}
}
私はアンドロイドのラッパーに精通していません。一般的にsqliteのように、トランザクションが完了していない場合、その動作が期待されます。私はまた、空のキャッチがコードレビューに合格することを許可しません。あなたは奇妙な行動を求めています。 :) –
空のキャッチについては、私は開発の初期段階にあります。この時点で、私はただの機能を手に入れようとしています。そして、私は戻って例外のようなものに対処します。 – Jonah
ちょっと質問がありますが、loadRoadsではgetReadableDatabase()を使用してgetWriteableDatabase呼び出しでオープンされたハンドルを閉じるべきではありませんか? –