Don't touch the cursor in the background
This prevents accessing a potentially closed cursor when doing batch operations that will inevitable cause the the list to be reloaded (and cursor to be invalidated) as the first of the messages are touched Bug: 5051730 Change-Id: I90328ee02eafe6ad238d8c57e88a3d96259f6547
This commit is contained in:
parent
af5826cc7a
commit
5fb6c5d4de
@ -69,7 +69,9 @@ import com.android.emailcommon.provider.Mailbox;
|
|||||||
import com.android.emailcommon.utility.EmailAsyncTask;
|
import com.android.emailcommon.utility.EmailAsyncTask;
|
||||||
import com.android.emailcommon.utility.Utility;
|
import com.android.emailcommon.utility.Utility;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -860,16 +862,13 @@ public class MessageListFragment extends ListFragment
|
|||||||
toggleMultiple(selectedSet, new MultiToggleHelper() {
|
toggleMultiple(selectedSet, new MultiToggleHelper() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getField(long messageId, Cursor c) {
|
public boolean getField(Cursor c) {
|
||||||
return c.getInt(MessagesAdapter.COLUMN_READ) == 0;
|
return c.getInt(MessagesAdapter.COLUMN_READ) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setField(long messageId, Cursor c, boolean newValue) {
|
public void setField(long messageId, boolean newValue) {
|
||||||
boolean oldValue = getField(messageId, c);
|
mController.setMessageReadSync(messageId, !newValue);
|
||||||
if (oldValue != newValue) {
|
|
||||||
mController.setMessageReadSync(messageId, !newValue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -883,16 +882,13 @@ public class MessageListFragment extends ListFragment
|
|||||||
toggleMultiple(selectedSet, new MultiToggleHelper() {
|
toggleMultiple(selectedSet, new MultiToggleHelper() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getField(long messageId, Cursor c) {
|
public boolean getField(Cursor c) {
|
||||||
return c.getInt(MessagesAdapter.COLUMN_FAVORITE) != 0;
|
return c.getInt(MessagesAdapter.COLUMN_FAVORITE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setField(long messageId, Cursor c, boolean newValue) {
|
public void setField(long messageId, boolean newValue) {
|
||||||
boolean oldValue = getField(messageId, c);
|
mController.setMessageFavoriteSync(messageId, newValue);
|
||||||
if (oldValue != newValue) {
|
|
||||||
mController.setMessageFavoriteSync(messageId, newValue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -910,19 +906,17 @@ public class MessageListFragment extends ListFragment
|
|||||||
/**
|
/**
|
||||||
* Return true if the field of interest is "set". If one or more are false, then our
|
* Return true if the field of interest is "set". If one or more are false, then our
|
||||||
* bulk action will be to "set". If all are set, our bulk action will be to "clear".
|
* bulk action will be to "set". If all are set, our bulk action will be to "clear".
|
||||||
* @param messageId the message id of the current message
|
|
||||||
* @param c the cursor, positioned to the item of interest
|
* @param c the cursor, positioned to the item of interest
|
||||||
* @return true if the field at this row is "set"
|
* @return true if the field at this row is "set"
|
||||||
*/
|
*/
|
||||||
public boolean getField(long messageId, Cursor c);
|
public boolean getField(Cursor c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set or clear the field of interest; setField is called asynchronously via EmailAsyncTask
|
* Set or clear the field of interest; setField is called asynchronously via EmailAsyncTask
|
||||||
* @param messageId the message id of the current message
|
* @param messageId the message id of the current message
|
||||||
* @param c the cursor, positioned to the item of interest
|
|
||||||
* @param newValue the new value to be set at this row
|
* @param newValue the new value to be set at this row
|
||||||
*/
|
*/
|
||||||
public void setField(long messageId, Cursor c, boolean newValue);
|
public void setField(long messageId, boolean newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -935,33 +929,35 @@ public class MessageListFragment extends ListFragment
|
|||||||
*/
|
*/
|
||||||
private void toggleMultiple(final Set<Long> selectedSet, final MultiToggleHelper helper) {
|
private void toggleMultiple(final Set<Long> selectedSet, final MultiToggleHelper helper) {
|
||||||
final Cursor c = mListAdapter.getCursor();
|
final Cursor c = mListAdapter.getCursor();
|
||||||
boolean anyWereFound = false;
|
if (c == null || c.isClosed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final HashMap<Long, Boolean> setValues = Maps.newHashMap();
|
||||||
boolean allWereSet = true;
|
boolean allWereSet = true;
|
||||||
|
|
||||||
c.moveToPosition(-1);
|
c.moveToPosition(-1);
|
||||||
while (c.moveToNext()) {
|
while (c.moveToNext()) {
|
||||||
long id = c.getInt(MessagesAdapter.COLUMN_ID);
|
long id = c.getInt(MessagesAdapter.COLUMN_ID);
|
||||||
if (selectedSet.contains(Long.valueOf(id))) {
|
if (selectedSet.contains(id)) {
|
||||||
anyWereFound = true;
|
boolean value = helper.getField(c);
|
||||||
if (!helper.getField(id, c)) {
|
setValues.put(id, value);
|
||||||
allWereSet = false;
|
allWereSet = allWereSet && value;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anyWereFound) {
|
if (!setValues.isEmpty()) {
|
||||||
final boolean newValue = !allWereSet;
|
final boolean newValue = !allWereSet;
|
||||||
c.moveToPosition(-1);
|
c.moveToPosition(-1);
|
||||||
|
// TODO: we should probably put up a dialog or some other progress indicator for this.
|
||||||
EmailAsyncTask.runAsyncParallel(new Runnable() {
|
EmailAsyncTask.runAsyncParallel(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
while (c.moveToNext()) {
|
for (long id : setValues.keySet()) {
|
||||||
long id = c.getInt(MessagesAdapter.COLUMN_ID);
|
if (setValues.get(id) != newValue) {
|
||||||
if (selectedSet.contains(Long.valueOf(id))) {
|
helper.setField(id, newValue);
|
||||||
helper.setField(id, c, newValue);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -969,12 +965,12 @@ public class MessageListFragment extends ListFragment
|
|||||||
/**
|
/**
|
||||||
* Test selected messages for showing appropriate labels
|
* Test selected messages for showing appropriate labels
|
||||||
* @param selectedSet
|
* @param selectedSet
|
||||||
* @param column_id
|
* @param columnId
|
||||||
* @param defaultflag
|
* @param defaultflag
|
||||||
* @return true when the specified flagged message is selected
|
* @return true when the specified flagged message is selected
|
||||||
*/
|
*/
|
||||||
private boolean testMultiple(Set<Long> selectedSet, int column_id, boolean defaultflag) {
|
private boolean testMultiple(Set<Long> selectedSet, int columnId, boolean defaultflag) {
|
||||||
Cursor c = mListAdapter.getCursor();
|
final Cursor c = mListAdapter.getCursor();
|
||||||
if (c == null || c.isClosed()) {
|
if (c == null || c.isClosed()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -982,7 +978,7 @@ public class MessageListFragment extends ListFragment
|
|||||||
while (c.moveToNext()) {
|
while (c.moveToNext()) {
|
||||||
long id = c.getInt(MessagesAdapter.COLUMN_ID);
|
long id = c.getInt(MessagesAdapter.COLUMN_ID);
|
||||||
if (selectedSet.contains(Long.valueOf(id))) {
|
if (selectedSet.contains(Long.valueOf(id))) {
|
||||||
if (c.getInt(column_id) == (defaultflag ? 1 : 0)) {
|
if (c.getInt(columnId) == (defaultflag ? 1 : 0)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user