2012-02-23 38 views
0

我的應用程序有一個SQLite數據庫來包含高速公路列表。它將它們全部顯示在列表中。它首先嚐試查詢道路的數據庫。如果查詢沒有返回任何內容,它會調用另一種方法從遠程服務器下載列表並填充數據庫。之後返回,它立即再次查詢數據庫。Android:SQLite查詢返回0行沒有重新加載?

這就是它應該如何工作。它的實際工作原理是,第一個查詢總是什麼都不返回。它直接下載新的列表,它將列表插入數據庫,然後再次查詢。第二個查詢總是返回正確的結果。奇怪的是,我可以在沒有退出應用程序的情況下重複操作。使用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

我不熟悉android的包裝。就一般的sqlite而言,如果事務沒有完成,我會期待這種行爲。我也不會允許那些空的漁獲物通過代碼審查。你在問奇怪的行爲。 :) – 2012-02-25 03:23:24

+0

關於空捕獲量,我處於開發的早期階段。在這一點上,我只是試圖獲得功能,然後我會回去處理例外情況。 – Jonah 2012-02-25 05:04:19

+1

只是幾個問題 - 但在loadRoads中,您不應該使用getReadableDatabase()並關閉由getWriteableDatabase調用打開的句柄嗎? – 2012-02-25 05:48:34

回答

1

我已經在過去有了極大的問題與不關閉數據庫處理 - 通常我會在SQLiteOpenHelper子類中執行所有數據庫操作,保持對數據庫的引用,以原子方式打開和關閉數據庫。