我正在寻找一种方法来访问尚未同步到Parse云服务器的新创建的本地ParseObject。由于没有objectId值,因此无法通过本地数据存储区查询objectId,并且看起来localId(看起来它在本地创建了一个唯一标识符)被锁定(否则这将是一个非问题,因为我可以使用我的内容提供商负责细节)。由于ParseObject类不是Parizable的Serializable,因此无法通过Intent传递它。为了注意我的任务的复杂性,我有3级ParseObjects(ParseObject> Array [ParseObjects]> Array [ParseObjects])。基本上我正在寻找Parse是否具有完全离线功能。
TL:DR 基本上我希望能够在创建后立即访问不同Activity中的单个ParseObject。这个问题是否具有Parse和ParseObjects的实际应用,或者我将不得不实施一些认真的工作?
答案 0 :(得分:0)
我相信ParseObjects是可序列化的,所以将它们放入Bundle然后将该Bundle放入Intent
当前活动中的
Intent mIntent = new Intent(currentActivityReference, DestinationActivity.class);
Bundle mBundle = new Bundle();
mBundle.putSerializable("object", mParseObject);
mIntent.putExtras(mBundle);
startActivity(mIntent);
目的地活动中的
使用getIntent().getExtras()
检索意图,这是一个Bundle对象,因此可序列化的.getSerializable("object")
有一个getter,但你必须将它转换为(ParseObject)
答案 1 :(得分:0)
因此,我能够将所有内容保留在已有的结构范围内,以解决此问题(同步适配器和Parse API)。基本上我所要做的就是利用Parse的现有" setObjectId"功能
注意:这仅适用于现有的Content Provider / SQLiteDatabase
我为本地存储的新ParseObject创建了一个临时唯一ID。此唯一值基于内容提供程序中的最大索引号,即存储我的对象(对于我的同步适配器)。
//query to get the max ID from the Content Provider (used with the sync adapter)
Cursor cursor = context.getContentResolver().query(
WorkoutContract.Entry.CONTENT_URI,
new String[]{"MAX(" + WorkoutContract.Entry._ID + ")"},
null, null, null
);
long idx = 1; //default max index if there are no records
if (cursor.moveToFirst())
idx = cursor.getInt(0) + 1;
final long maxIndex = idx;
cursor.close();
//this is the temporary ID used for storing, a String constant prepended to the max index
String localID = WorkoutContract.LOCAL_WORKOUT_ID + maxIndex;
然后我使用pin()方法在本地存储这个ParseObject,然后在Content Provider中插入一个不仅保留表中的ID来迭代表中的最大索引。
//need to insert a dummy value into the Content Provider so the max _ID iterates
ContentValues workoutValues = new ContentValues();
//the COLUMN_WORKOUT_ID constant refers to the column which holds the ParseObjects ID
workoutValues.put(WorkoutContract.Entry.COLUMN_WORKOUT_ID, localID);
context.getContentResolver().insert(
WorkoutContract.Entry.CONTENT_URI,
workoutValues);
然后我创建了另一个虚拟ParseObject,它具有与具有本地ID(没有本地ID)的属性相同的属性。然后通过saveEventually()函数将此ParseObject保存到服务器。 (注意:这将创建2个本地副本或ParseObject。要将空白副本保留在查询之外,只需省略具有空对象ID的ParseObjects。)
query.whereNotEqualTo("objectId", null);
在saveEventually()函数中,需要一个回调来替换旧的(本地)ParseObject以及Content提供程序中的localID值。在SaveCallback对象中,将服务器返回的ParseObject属性替换为本地属性(以考虑服务器查询期间所做的任何更改)。下面是SaveCallback的完整代码,其中tempObject是发送到Parse服务器的那个:
tempObject.saveEventually(new SaveCallback() {
//changes the local ParseObject's ID to the newly generated one
@Override
public void done(ParseException e) {
if (e == null) {
try {
//replaces the old ParseObject
tempObject.put(Workout.PARSE_FIELD_NAME, newWorkout.get(Workout.PARSE_FIELD_NAME));
tempObject.put(Workout.PARSE_FIELD_OWNER, ParseUser.getCurrentUser());
tempObject.put(Workout.PARSE_FIELD_DESCRIPTION, newWorkout.get(Workout.PARSE_FIELD_DESCRIPTION));
tempObject.pin();
newWorkout.unpinInBackground(new DeleteCallback() {
@Override
public void done(ParseException e) {
Log.i(TAG, "Object unpinned");
}
});
} catch (ParseException e1) {
e1.printStackTrace();
}
//update to content provider with the new ID
ContentValues mUpdateValues = new ContentValues();
String mSelectionClause = WorkoutContract.Entry._ID + "= ?";
String[] mSelectionArgs = {Long.toString(maxIndex)};
mUpdateValues.put(WorkoutContract.Entry.COLUMN_WORKOUT_ID, tempObject.getObjectId());
mUpdateValues.put(WorkoutContract.Entry.COLUMN_UPDATED, tempObject.getUpdatedAt().getTime());
context.getContentResolver().update(
WorkoutContract.Entry.CONTENT_URI,
mUpdateValues,
mSelectionClause,
mSelectionArgs
);
}
}
});
要在另一个Activity中获取本地ParseObject,只需在Intent中传递本地objectId并加载它。但是,内容提供程序上的ParseObject索引也需要传递(或者可以从唯一的本地ID中检索),因此如果再次检索ParseObject,您可以检查内容提供程序以获取更新的对象ID和查询正确的ParseObject。
这可以使用一些改进,但现在它可以工作。