gpt4 book ai didi

java - 为什么 ContentProvider 在 App 更新后返回空光标?

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:41:14 26 4
gpt4 key购买 nike

我最近推出了我的应用程序的更新,我从一些用户那里得到了他们的数据丢失的反馈。经过一些分析,我确定我使用的单个内容提供程序总是返回一个空光标。

我没有更改内容提供者本身的代码或查询它的代码。数据格式没有改变。该问题仅在少数设备上可见,而且似乎仅限于 Android 6.0(主要是三星,但也有一些 LG 设备)。不仅初始数据丢失,而且所有后续插入都不会持久化

可以通过全新安装应用(删除 + 安装)来解决此问题。

有没有人知道如何解决/解决这个问题?

我认为这不相关,但这是代码:

Cursor cursor = contentResolver.query(Columns.contentUri(), Columns.ALARM_QUERY_COLUMNS, null, null, Columns.DEFAULT_SORT_ORDER);

List<AlarmActiveRecord> alarms = new ArrayList<AlarmActiveRecord>();
try {
if (cursor.moveToFirst()) {
do {
alarms.add(factory.create(cursor));
} while (cursor.moveToNext());
}
} finally {
cursor.close();
}
return alarms;

和内容提供者:

@Override
public Cursor query(Uri url, String[] projectionIn, String selection, String[] selectionArgs, String sort) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();

// Generate the body of the query
Preconditions.checkArgument(sURLMatcher.match(url) == ALARMS, "Invalid URL %s", url);
qb.setTables("alarms");

SQLiteDatabase db = mOpenHelper.getReadableDatabase();
Cursor ret;
try {
ret = qb.query(db, projectionIn, selection, selectionArgs, null, null, sort);
} catch (SQLException e) {
log.e("query failed because of " + e.getMessage() + ", recreating DB");
db.execSQL("DROP TABLE IF EXISTS alarms");
// I know this is not nice to call onCreate() by ourselves :-)
mOpenHelper.onCreate(db);
ret = qb.query(db, projectionIn, selection, selectionArgs, null, null, sort);
}
if (ret != null) {
ret.setNotificationUri(getContext().getContentResolver(), url);
}

return ret;
}

还有数据库助手:

public class AlarmDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "alarms.db";
private static final int DATABASE_VERSION = 5;
private final Logger log;

public AlarmDatabaseHelper(Context context, Logger log) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.log = log;
}

@Override
public void onCreate(SQLiteDatabase db) {
// @formatter:off
db.execSQL("CREATE TABLE alarms (" +
"_id INTEGER PRIMARY KEY," +
"hour INTEGER, " +
"minutes INTEGER, " +
"daysofweek INTEGER, " +
"alarmtime INTEGER, " +
"enabled INTEGER, " +
"vibrate INTEGER, " +
"message TEXT, " +
"alert TEXT, " +
"prealarm INTEGER, " +
"state STRING);");
// @formatter:on
// insert default alarms
String insertMe = "INSERT INTO alarms " + "(hour, minutes, daysofweek, alarmtime, enabled, vibrate, "
+ "message, alert, prealarm, state) VALUES ";
db.execSQL(insertMe + "(8, 30, 31, 0, 0, 1, '', '', 0, '');");
db.execSQL(insertMe + "(9, 00, 96, 0, 0, 1, '', '', 0, '');");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
log.d("Upgrading alarms database from version " + oldVersion + " to " + currentVersion
+ ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS alarms");
onCreate(db);
}

public Uri commonInsert(ContentValues values) {
SQLiteDatabase db = getWritableDatabase();
long rowId = db.insert("alarms", Columns.MESSAGE, values);
if (rowId < 0) throw new SQLException("Failed to insert row");
log.d("Added alarm rowId = " + rowId);

return ContentUris.withAppendedId(Columns.contentUri(), rowId);
}
}

最佳答案

迁移脚本导致了所描述的行为。 DROP TABLE 字面意思就是它所说的,因此所有以前输入的记录都将丢失,除非旧版本的数据库已备份到云端。此问题可能不仅限于三星或 LG 设备,因为该部分是明确的:

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) {
db.execSQL("DROP TABLE IF EXISTS alarms");
}

您需要将数据库从一个版本迁移到下一个版本;对于 example .

Room 也支持 Migrating Room databases (这只是相同的场景)。

关于java - 为什么 ContentProvider 在 App 更新后返回空光标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57384320/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com