I have a situation in which I need to insert a row at a date and update all the entries after a particular date in an activity.
For this, I thought I'll load the entries after the date with a LoaderManager
Callback and use a ContentProviderOperation
array to update all of it in batch from the onLoadFinished()
method.
The problem I am facing is that I have setNotificationUri
to the cursor and because of that the onLoadfinished
is called again, which inserts the row again and the cycle continues (not setting the notification Uri
is not an option for me).
Is there any elegant solution to stop the recursive call?
Below is the simplified code of my onCreateLoader
and onLoadFinished
:
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
//retrieve data before the start date
mStartDate = ProjectContract.getDateFromDb(mUserProjectEntryData.getAsString(ProjectContract.ProjectEntryTable.COLUMN_DATETEXT));
Date nextDate = Utilities.addDays(mStartDate,1);
String sortOrder = ProjectContract.ProjectEntryTable.COLUMN_DATETEXT + " ASC";
Uri projectEntryUri = ProjectContract.ProjectEntryTable.buildProjectEntryWithStartDateUri(mProjectId,
ProjectContract.getDbDateString(nextDate));
return new CursorLoader(
this,
projectEntryUri,
PROJECT_ENTRY_COLUMNS,
null,
null,
sortOrder
);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mDbOperations = new ArrayList<ContentProviderOperation>();
long newTotalCount;
String selection = ProjectContract.ProjectEntryTable.COLUMN_PROJECT_ID + " = ? AND "
+ ProjectContract.ProjectEntryTable.COLUMN_DATETEXT + " = ? ";
//Some code to calculate the entry needed
mDbOperations.add(
ContentProviderOperation.newInsert(ProjectContract.ProjectEntryTable.CONTENT_URI)
.withValues(mUserProjectEntryData)
.withYieldAllowed(true)
.build()
);
while (data.moveToNext()) {
data.getString(COL_DATETEXT));
newTotalCount = mCurrentWordCount + data.getLong(COL_WORD_COUNT);
mDbOperations.add(ContentProviderOperation.newUpdate(ProjectContract.ProjectEntryTable.CONTENT_URI)
.withValue(ProjectContract.ProjectEntryTable.COLUMN_TOTAL_WORD_COUNT, newTotalCount)
.withSelection(selection, new String[]{
Long.toString(data.getLong(COL_PROJECT_ID)),
data.getString(COL_DATETEXT)
})
.build());
}
//Hacky solution I put in just to make the code working.
// data.close();
try {
getContentResolver().applyBatch(ProjectContract.CONTENT_AUTHORITY, mDbOperations);
} catch (RemoteException e) {
e.printStackTrace();
} catch (OperationApplicationException e) {
e.printStackTrace();
}
}
I ended up moving the db operations to a separate thread without using the loader callbacks