我对这个问题感到很困惑。我的应用程序的一般架构:
我正在使用Retrofit从Foursquare检索数据。 (因为我检查了答案很好。)在我的Service
课程中,我将数据保留在我的本地数据库中并在之后向我的Fragment
发送消息。我浏览了我的数据库,创建了表 - 但由于不明原因我的数据库保持空白。记录没有多大帮助。
这是我的相关代码。
WebService 类(我刚删除了我的密钥):
private void handleExploreVenues(Intent intent) {
String ll = intent.getStringExtra(EXTRAS_LL);
String radius = intent.getStringExtra(EXTRAS_RADIUS);
String limit = intent.getStringExtra(EXTRAS_LIMIT);
String offset = intent.getStringExtra(EXTRAS_OFFSET);
parametersMap = new HashMap<>();
parametersMap.put(EXTRAS_LL, ll);
parametersMap.put(EXTRAS_LIMIT, limit);
parametersMap.put(EXTRAS_RADIUS, radius);
parametersMap.put(EXTRAS_OFFSET, offset);
parametersMap.put("client_secret", "");//
parametersMap.put("client_id", "");//
parametersMap.put("v", "20160215");
parametersMap.put("venuePhotos", "1");
executor.submit(new Runnable() {
@Override
public void run() {
ApiRequests client = RESTClient.createRetrofitClient(ApiRequests.class);
Call<ExploreResponse> call = client.exploreVenues(parametersMap);
try {
exploreResponse = call.execute().body();
Log.i(LOG_TAG, "explore response is null: " + (exploreResponse == null));
if (exploreResponse != null) {
DBDataSource dbDataSource = new DBDataSource(getApplicationContext());
dbDataSource.open();
dbDataSource.saveVenueList(exploreResponse.getResponse().getGroups().get(0).getItems());
dbDataSource.close();
OttoBus.getInstance().post(new VenuesPreparedEvent());
}
} catch (IOException e) {
Log.i(LOG_TAG, "Exception during exploring venues");
e.printStackTrace();
}
}
});
}
DBDataSource 类:
public class DBDataSource {
private SQLiteDatabase database;
private DBHelper dbHelper;
private final String LOG_TAG = DBDataSource.class.getSimpleName();
private String[] allColumnsVenues = {
DBHelper.COLUMN_ID,
DBHelper.COLUMN_VENUE_NAME,
DBHelper.COLUMN_RATING,
DBHelper.COLUMN_RATING_COLOR,
DBHelper.COLUMN_LOCATION_ID,
DBHelper.COLUMN_PHOTO_ID,
DBHelper.COLUMN_PHONE};
private String[] allColumnsLocation = {
DBHelper.COLUMN_ID,
DBHelper.COLUMN_ADDRESS,
DBHelper.COLUMN_LAT,
DBHelper.COLUMN_LNG
};
private String[] allColumnsPhoto = {
DBHelper.COLUMN_ID,
DBHelper.COLUMN_PREFIX,
DBHelper.COLUMN_SUFFIX
};
public DBDataSource(Context context) {
dbHelper = DBHelper.getInstance(context);
}
public void open() throws SQLException {
database = dbHelper.getWritableDatabase();
}
public void close() {
database.close();
}
public void saveVenue(Venue venue) {
ContentValues values = new ContentValues();
values.put(DBHelper.COLUMN_ID, venue.getId());
values.put(DBHelper.COLUMN_VENUE_NAME, venue.getName());
values.put(DBHelper.COLUMN_RATING, venue.getRating());
values.put(DBHelper.COLUMN_RATING_COLOR, venue.getRatingColor());
values.put(DBHelper.COLUMN_PHONE, venue.getContact().getFormattedPhone());
values.put(DBHelper.COLUMN_LOCATION_ID, saveLocation(venue.getLocation()));
values.put(DBHelper.COLUMN_PHOTO_ID, savePhoto(venue.getFeaturedPhotos().getItems().get(0)));
long insertResp = database.insertWithOnConflict(DBHelper.TABLE_VENUES, null, values, SQLiteDatabase.CONFLICT_REPLACE);
Log.i(LOG_TAG, "inserting venue response " + insertResp);
}
public void saveVenueList(List<Item> itemList) {
database.beginTransaction();
try {
for (Item item : itemList) {
Venue venue = item.getVenue();
saveVenue(venue);
}
} catch (Exception e) {
Log.e(LOG_TAG, "exception during venue saving");
e.printStackTrace();
} finally {
database.endTransaction();
}
}
public List<Venue> getAllVenues() {
List<Venue> venueList = new ArrayList<>();
Cursor cursor = database.query(DBHelper.TABLE_VENUES, allColumnsVenues, null, null, null,
null, null);
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
Venue venue = cursorToVenue(cursor);
venueList.add(venue);
cursor.moveToNext();
}
return venueList;
}
public long saveLocation(Location location) {
ContentValues values = new ContentValues();
values.put(DBHelper.COLUMN_ADDRESS, location.getAddress());
values.put(DBHelper.COLUMN_LNG, location.getLng());
values.put(DBHelper.COLUMN_LAT, location.getLat());
long insertLocationResp = database.insertWithOnConflict(DBHelper.TABLE_LOCATIONS, null, values, SQLiteDatabase.CONFLICT_REPLACE);
Log.i(LOG_TAG, "inserting location response " + insertLocationResp);
return insertLocationResp;
}
public String savePhoto(Item___ item___) {
ContentValues values = new ContentValues();
values.put(DBHelper.COLUMN_ID, item___.getId());
values.put(DBHelper.COLUMN_PREFIX, item___.getPrefix());
values.put(DBHelper.COLUMN_SUFFIX, item___.getSuffix());
long insertPhotoResp = database.insertWithOnConflict(DBHelper.TABLE_PHOTOS, null, values, SQLiteDatabase.CONFLICT_REPLACE);
Log.i(LOG_TAG, "inserting photo response " + insertPhotoResp);
return item___.getId();
}
private Location getRelevantLocation(int locationID) {
String restrict = DBHelper.COLUMN_ID + "=" + locationID;
Cursor cursor = database.query(true, DBHelper.TABLE_LOCATIONS, allColumnsLocation, restrict, null, null, null,
null, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
return cursorToLocation(cursor);
}
// Make sure to close the cursor
if (cursor != null) {
cursor.close();
}
return null;
}
private Location cursorToLocation(Cursor cursor) {
Location location = new Location();
location.setAddress(cursor.getString(1));
location.setLat(cursor.getDouble(2));
location.setLng(cursor.getDouble(3));
return location;
}
private Photos getRelevantPhoto(int photoID) {
String restrict = DBHelper.COLUMN_ID + "=" + photoID;
Cursor cursor = database.query(true, DBHelper.TABLE_PHOTOS, allColumnsPhoto, restrict, null, null, null,
null, null);
if (cursor != null && cursor.getCount() > 0) {
cursor.moveToFirst();
//because of big amount of nested lists and object this part looks really ugly. Reconsider possible solutions
Item__ item__ = cursorToPhoto(cursor);
Photos photos = new Photos();
List<Item__> list = new ArrayList<>();
list.add(item__);
List<Group_> group_list = new ArrayList<>();
Group_ group = new Group_();
group.setItems(list);
group_list.add(group);
photos.setGroups(group_list);
return photos;
}
// Make sure to close the cursor
if (cursor != null) {
cursor.close();
}
return null;
}
private Item__ cursorToPhoto(Cursor cursor) {
Item__ item__ = new Item__();
item__.setId(cursor.getString(0));
item__.setPrefix(cursor.getString(1));
item__.setSuffix(cursor.getString(2));
return item__;
}
private Venue cursorToVenue(Cursor cursor) {
Venue venue = new Venue();
venue.setId(cursor.getString(0));
venue.setName(cursor.getString(1));
venue.setRating(cursor.getDouble(2));
venue.setRatingColor(cursor.getString(3));
venue.setLocation(getRelevantLocation(cursor.getInt(4)));
venue.setPhotos(getRelevantPhoto(cursor.getInt(5)));
Contact contact = new Contact();
contact.setPhone(cursor.getString(6));
venue.setContact(contact);
return venue;
}
}
我的 DBHelper 课程(以防我错过了什么):
public class DBHelper extends SQLiteOpenHelper {
private final String LOG_TAG = DBHelper.class.getSimpleName();
public static final String DB_NAME = "LocalVenues.db";
public static final int DB_VERSION = 1;
public static final String COLUMN_ID = "_id";
//TODO ADD PRICES TABLE AND REFERENCE
public static final String TABLE_VENUES = "venues";
public static final String COLUMN_VENUE_NAME = "name";
public static final String COLUMN_RATING = "rating";
public static final String COLUMN_RATING_COLOR = "rating_color";
public static final String COLUMN_LOCATION_ID = "location_id";
public static final String COLUMN_PHOTO_ID = "photo_id";
public static final String COLUMN_PHONE = "phone";
//tips
public static final String TABLE_TIPS = "tips";
public static final String COLUMN_VENUE_ID = "venue_id";
public static final String COLUMN_TIP_TEXT = "text";
public static final String COLUMN_AUTHOR_ID = "user_id";
//locations
public static final String TABLE_LOCATIONS = "locations";
public static final String COLUMN_ADDRESS = "address";
public static final String COLUMN_LAT = "lat";
public static final String COLUMN_LNG = "lng";
//authors
public static final String TABLE_USERS = "users";
public static final String COLUMN_FIRST_NAME = "first_name";
public static final String COLUMN_LAST_NAME = "last_name";
//photos
public static final String TABLE_PHOTOS = "photos";
public static final String COLUMN_PREFIX = "prefix";
public static final String COLUMN_SUFFIX = "suffix";
private static DBHelper dbHelperInstance;
private DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
public static synchronized DBHelper getInstance(Context context) {
if (dbHelperInstance == null) {
return dbHelperInstance = new DBHelper(context.getApplicationContext());
} else {
return dbHelperInstance;
}
}
@Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
db.setForeignKeyConstraintsEnabled(true);
}
@Override
public void onCreate(SQLiteDatabase db) {
String STM_CREATE_TABLE = "CREATE TABLE ";
String STM_PRIMARY_KEY = "PRIMARY KEY ";
String STM_FOREIGN_KEY = " FOREIGN KEY ";
String STM_REFERENCES = " REFERENCES ";
String STM_TEXT = " TEXT ";
String STM_AUTOINCREMENT = " AUTOINCREMENT, ";
String STM_TEXT_PRIMARY_KEY = STM_TEXT + STM_PRIMARY_KEY;
String STM_NOT_NULL = " NOT NULL, ";
String STM_REAL = " REAL ";
String STM_INTEGER = " INTEGER ";
String CREATE_TABLE_VENUES = STM_CREATE_TABLE + TABLE_VENUES + " ( " +
COLUMN_ID + STM_TEXT_PRIMARY_KEY + ", " +
COLUMN_VENUE_NAME + STM_TEXT + STM_NOT_NULL +
COLUMN_RATING + STM_REAL + STM_NOT_NULL +
COLUMN_RATING_COLOR + STM_TEXT + STM_NOT_NULL +
COLUMN_LOCATION_ID + STM_INTEGER + STM_NOT_NULL +
COLUMN_PHOTO_ID + STM_TEXT + STM_NOT_NULL +
COLUMN_PHONE + STM_TEXT + ", " +
STM_FOREIGN_KEY + "(" + COLUMN_LOCATION_ID + ")" + STM_REFERENCES + TABLE_LOCATIONS + "(" + COLUMN_ID + "), " +
STM_FOREIGN_KEY + "(" + COLUMN_PHOTO_ID + ")" + STM_REFERENCES + TABLE_PHOTOS + "(" + COLUMN_ID + ") "
+ ");";
String CREATE_TABLE_LOCATIONS = STM_CREATE_TABLE + TABLE_LOCATIONS + " ( " +
COLUMN_ID + STM_INTEGER + STM_PRIMARY_KEY + STM_AUTOINCREMENT +
COLUMN_ADDRESS + STM_TEXT + STM_NOT_NULL +
COLUMN_LAT + STM_REAL + STM_NOT_NULL +
COLUMN_LNG + STM_REAL + "NOT NULL"
+ ");";
String CREATE_TABLE_PHOTOS = STM_CREATE_TABLE + TABLE_PHOTOS + " ( " +
COLUMN_ID + STM_TEXT_PRIMARY_KEY + ", " +
COLUMN_PREFIX + STM_TEXT + STM_NOT_NULL +
COLUMN_SUFFIX + STM_TEXT + "NOT NULL"
+ ");";
String CREATE_TABLE_USERS = STM_CREATE_TABLE + TABLE_USERS + " ( " +
COLUMN_ID + STM_TEXT_PRIMARY_KEY + ", " +
COLUMN_PHOTO_ID + STM_TEXT + STM_NOT_NULL +
COLUMN_FIRST_NAME + STM_TEXT + STM_NOT_NULL +
COLUMN_LAST_NAME + STM_TEXT + STM_NOT_NULL +
STM_FOREIGN_KEY + " ( " + COLUMN_PHOTO_ID + " ) " + STM_REFERENCES + TABLE_PHOTOS + " (" + COLUMN_ID + " ) "
+ ");";
String CREATE_TABLE_TIPS = STM_CREATE_TABLE + TABLE_TIPS + " ( " +
COLUMN_ID + STM_TEXT_PRIMARY_KEY + ", " +
COLUMN_PHOTO_ID + STM_TEXT + STM_NOT_NULL +
COLUMN_VENUE_ID + STM_TEXT + STM_NOT_NULL +
COLUMN_AUTHOR_ID + STM_TEXT + STM_NOT_NULL +
COLUMN_TIP_TEXT + STM_TEXT + STM_NOT_NULL +
STM_FOREIGN_KEY + "(" + COLUMN_VENUE_ID + ")" + STM_REFERENCES + TABLE_VENUES + "(" + COLUMN_ID + "), " +
STM_FOREIGN_KEY + "(" + COLUMN_AUTHOR_ID + ")" + STM_REFERENCES + TABLE_USERS + "(" + COLUMN_ID + "), " +
STM_FOREIGN_KEY + "(" + COLUMN_PHOTO_ID + ")" + STM_REFERENCES + TABLE_PHOTOS + "(" + COLUMN_ID + ") "
+ ");";
Log.i(LOG_TAG, CREATE_TABLE_VENUES);
db.execSQL(CREATE_TABLE_VENUES);
Log.i(LOG_TAG, CREATE_TABLE_LOCATIONS);
db.execSQL(CREATE_TABLE_LOCATIONS);
Log.i(LOG_TAG, CREATE_TABLE_PHOTOS);
db.execSQL(CREATE_TABLE_PHOTOS);
Log.i(LOG_TAG, CREATE_TABLE_USERS);
db.execSQL(CREATE_TABLE_USERS);
Log.i(LOG_TAG, CREATE_TABLE_TIPS);
db.execSQL(CREATE_TABLE_TIPS);
}
//The simplest implementation of onUpgrade() method
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
String STM_DROP_TABLE_IF_EXISTS = "DROP TABLE IF EXISTS ";
if (oldVersion != newVersion) {
db.execSQL(STM_DROP_TABLE_IF_EXISTS + TABLE_VENUES);
db.execSQL(STM_DROP_TABLE_IF_EXISTS + TABLE_LOCATIONS);
db.execSQL(STM_DROP_TABLE_IF_EXISTS + TABLE_PHOTOS);
db.execSQL(STM_DROP_TABLE_IF_EXISTS + TABLE_TIPS);
db.execSQL(STM_DROP_TABLE_IF_EXISTS + TABLE_USERS);
}
}
}
在我的日志中,我检查了插入代码,它看起来很奇怪:
2965-2982/com.localvenues I/WebService: explore response is null: false
2965-2982/com.localvenues I/DBDataSource: inserting location response 1
2965-2982/com.localvenues I/DBDataSource: inserting photo response 1
2965-2982/com.localvenues I/DBDataSource: inserting venue response 1
2965-2982/com.localvenues I/DBDataSource: inserting location response 2
2965-2982/com.localvenues I/DBDataSource: inserting photo response 2
2965-2982/com.localvenues I/DBDataSource: inserting venue response 2
2965-2982/com.localvenues I/DBDataSource: inserting location response 3
2965-2982/com.localvenues I/DBDataSource: inserting photo response 3
2965-2982/com.localvenues I/DBDataSource: inserting venue response 3
2965-2982/com.localvenues I/DBDataSource: inserting location response 4
2965-2982/com.localvenues I/DBDataSource: inserting photo response 4
2965-2982/com.localvenues I/DBDataSource: inserting venue response 4
2965-2982/com.localvenues I/DBDataSource: inserting location response 5
2965-2982/com.localvenues I/DBDataSource: inserting photo response 5
2965-2982/com.localvenues I/DBDataSource: inserting venue response 5
2965-2982/com.localvenues I/DBDataSource: inserting location response 6
2965-2982/com.localvenues I/DBDataSource: inserting photo response 6
2965-2982/com.localvenues I/DBDataSource: inserting venue response 6
2965-2982/com.localvenues I/DBDataSource: inserting location response 7
2965-2982/com.localvenues I/DBDataSource: inserting photo response 7
2965-2982/com.localvenues I/DBDataSource: inserting venue response 7
2965-2982/com.localvenues I/DBDataSource: inserting location response 8
2965-2982/com.localvenues I/DBDataSource: inserting photo response 8
2965-2982/com.localvenues I/DBDataSource: inserting venue response 8
2965-2982/com.localvenues I/DBDataSource: inserting location response 9
2965-2982/com.localvenues I/DBDataSource: inserting photo response 9
2965-2982/com.localvenues I/DBDataSource: inserting venue response 9
2965-2982/com.localvenues I/DBDataSource: inserting location response 10
2965-2982/com.localvenues I/DBDataSource: inserting photo response 10
2965-2982/com.localvenues I/DBDataSource: inserting venue response 10
2965-2982/com.localvenues I/ListFragment: event from service received
2965-2982/com.localvenues I/ListFragment: check venues from DB - is empty: true
我只是不知道问题出在哪里。也不例外,也没有警告。我将不胜感激任何帮助。提前谢谢。
答案 0 :(得分:2)
您需要在setTransactionSuccessful()
之前调用endTransaction()
来实际提交对数据库的更改。未设置为成功的事务是回滚。