mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-27 19:52:17 -05:00
Refactored message loading for view
--> Perfomance improvement: the code was doing duplicates calls to the server to set SEEN flag and duplicate access to the db.
This commit is contained in:
parent
7d98ed60ad
commit
5ab77dcd64
@ -1751,6 +1751,20 @@ s * critical data as fast as possible, and then we'll fill in the de
|
|||||||
setMessageFlag(account, folder, uid, Flag.SEEN, seen);
|
setMessageFlag(account, folder, uid, Flag.SEEN, seen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the message with the given account, folder and uid either Seen or not Seen.
|
||||||
|
* @param account
|
||||||
|
* @param folder
|
||||||
|
* @param uid
|
||||||
|
* @param seen
|
||||||
|
*/
|
||||||
|
public void markMessageRead(
|
||||||
|
final Account account,
|
||||||
|
final Folder folder,
|
||||||
|
final Message message,
|
||||||
|
final boolean seen) {
|
||||||
|
setMessageFlag(account, folder, message, Flag.SEEN, seen);
|
||||||
|
}
|
||||||
|
|
||||||
public void setMessageFlag(
|
public void setMessageFlag(
|
||||||
final Account account,
|
final Account account,
|
||||||
@ -1766,28 +1780,52 @@ s * critical data as fast as possible, and then we'll fill in the de
|
|||||||
localFolder.open(OpenMode.READ_WRITE);
|
localFolder.open(OpenMode.READ_WRITE);
|
||||||
|
|
||||||
Message message = localFolder.getMessage(uid);
|
Message message = localFolder.getMessage(uid);
|
||||||
|
|
||||||
|
setMessageFlag(account, localFolder, message, flag, newState);
|
||||||
|
|
||||||
|
localFolder.close(false);
|
||||||
|
}
|
||||||
|
catch (MessagingException me) {
|
||||||
|
addErrorMessage(account, me);
|
||||||
|
|
||||||
|
throw new RuntimeException(me);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessageFlag(
|
||||||
|
final Account account,
|
||||||
|
final Folder folder,
|
||||||
|
final Message message,
|
||||||
|
final Flag flag,
|
||||||
|
final boolean newState) {
|
||||||
|
// TODO: put this into the background, but right now that causes odd behavior
|
||||||
|
// because the FolderMessageList doesn't have its own cache of the flag states
|
||||||
|
try {
|
||||||
|
String uid = message.getUid();
|
||||||
|
String folderName = folder.getName();
|
||||||
|
|
||||||
message.setFlag(flag, newState);
|
message.setFlag(flag, newState);
|
||||||
|
|
||||||
// Allows for re-allowing sending of messages that could not be sent
|
// Allows for re-allowing sending of messages that could not be sent
|
||||||
if (flag == Flag.FLAGGED && newState == false
|
if (flag == Flag.FLAGGED && newState == false
|
||||||
&& uid != null
|
&& uid != null
|
||||||
&& account.getOutboxFolderName().equals(folder))
|
&& account.getOutboxFolderName().equals(folderName))
|
||||||
{
|
{
|
||||||
sendCount.remove(uid);
|
sendCount.remove(uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MessagingListener l : getListeners()) {
|
for (MessagingListener l : getListeners()) {
|
||||||
l.folderStatusChanged(account, folder);
|
l.folderStatusChanged(account, folderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (account.getErrorFolderName().equals(folder))
|
if (account.getErrorFolderName().equals(folderName))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingCommand command = new PendingCommand();
|
PendingCommand command = new PendingCommand();
|
||||||
command.command = PENDING_COMMAND_SET_FLAG;
|
command.command = PENDING_COMMAND_SET_FLAG;
|
||||||
command.arguments = new String[] { folder, uid, Boolean.toString(newState), flag.toString() };
|
command.arguments = new String[] { folderName, uid, Boolean.toString(newState), flag.toString() };
|
||||||
queuePendingCommand(account, command);
|
queuePendingCommand(account, command);
|
||||||
processPendingCommands(account);
|
processPendingCommands(account);
|
||||||
}
|
}
|
||||||
@ -1796,7 +1834,7 @@ s * critical data as fast as possible, and then we'll fill in the de
|
|||||||
|
|
||||||
throw new RuntimeException(me);
|
throw new RuntimeException(me);
|
||||||
}
|
}
|
||||||
}
|
}//setMesssageFlag
|
||||||
|
|
||||||
public void clearAllPending(final Account account)
|
public void clearAllPending(final Account account)
|
||||||
{
|
{
|
||||||
@ -1817,18 +1855,15 @@ s * critical data as fast as possible, and then we'll fill in the de
|
|||||||
final String uid, MessagingListener listener) {
|
final String uid, MessagingListener listener) {
|
||||||
put("loadMessageForViewRemote", listener, new Runnable() {
|
put("loadMessageForViewRemote", listener, new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
|
Folder remoteFolder = null;
|
||||||
|
LocalFolder localFolder = null;
|
||||||
try {
|
try {
|
||||||
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||||
LocalFolder localFolder = (LocalFolder) localStore.getFolder(folder);
|
localFolder = (LocalFolder) localStore.getFolder(folder);
|
||||||
localFolder.open(OpenMode.READ_WRITE);
|
localFolder.open(OpenMode.READ_WRITE);
|
||||||
|
|
||||||
Message message = localFolder.getMessage(uid);
|
Message message = localFolder.getMessage(uid);
|
||||||
|
|
||||||
// This is a view message request, so mark it read
|
|
||||||
if (!message.isSet(Flag.SEEN)) {
|
|
||||||
markMessageRead(account, folder, uid, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.isSet(Flag.X_DOWNLOADED_FULL)) {
|
if (message.isSet(Flag.X_DOWNLOADED_FULL)) {
|
||||||
/*
|
/*
|
||||||
* If the message has been synchronized since we were called we'll
|
* If the message has been synchronized since we were called we'll
|
||||||
@ -1838,40 +1873,36 @@ s * critical data as fast as possible, and then we'll fill in the de
|
|||||||
fp.add(FetchProfile.Item.ENVELOPE);
|
fp.add(FetchProfile.Item.ENVELOPE);
|
||||||
fp.add(FetchProfile.Item.BODY);
|
fp.add(FetchProfile.Item.BODY);
|
||||||
localFolder.fetch(new Message[] { message }, fp, null);
|
localFolder.fetch(new Message[] { message }, fp, null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
* At this point the message is not available, so we need to download it
|
||||||
|
* fully if possible.
|
||||||
|
*/
|
||||||
|
|
||||||
for (MessagingListener l : getListeners()) {
|
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||||
l.loadMessageForViewBodyAvailable(account, folder, uid, message);
|
remoteFolder = remoteStore.getFolder(folder);
|
||||||
}
|
remoteFolder.open(OpenMode.READ_WRITE);
|
||||||
for (MessagingListener l : getListeners()) {
|
|
||||||
l.loadMessageForViewFinished(account, folder, uid, message);
|
// Get the remote message and fully download it
|
||||||
}
|
Message remoteMessage = remoteFolder.getMessage(uid);
|
||||||
localFolder.close(false);
|
FetchProfile fp = new FetchProfile();
|
||||||
return;
|
fp.add(FetchProfile.Item.BODY);
|
||||||
|
remoteFolder.fetch(new Message[] { remoteMessage }, fp, null);
|
||||||
|
|
||||||
|
// Store the message locally and load the stored message into memory
|
||||||
|
localFolder.appendMessages(new Message[] { remoteMessage });
|
||||||
|
message = localFolder.getMessage(uid);
|
||||||
|
localFolder.fetch(new Message[] { message }, fp, null);
|
||||||
|
|
||||||
|
// Mark that this message is now fully synched
|
||||||
|
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// This is a view message request, so mark it read
|
||||||
* At this point the message is not available, so we need to download it
|
if (!message.isSet(Flag.SEEN)) {
|
||||||
* fully if possible.
|
markMessageRead(account, localFolder, message, true);
|
||||||
*/
|
}
|
||||||
|
|
||||||
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
|
||||||
Folder remoteFolder = remoteStore.getFolder(folder);
|
|
||||||
remoteFolder.open(OpenMode.READ_WRITE);
|
|
||||||
|
|
||||||
// Get the remote message and fully download it
|
|
||||||
Message remoteMessage = remoteFolder.getMessage(uid);
|
|
||||||
FetchProfile fp = new FetchProfile();
|
|
||||||
fp.add(FetchProfile.Item.BODY);
|
|
||||||
remoteFolder.fetch(new Message[] { remoteMessage }, fp, null);
|
|
||||||
|
|
||||||
// Store the message locally and load the stored message into memory
|
|
||||||
localFolder.appendMessages(new Message[] { remoteMessage });
|
|
||||||
message = localFolder.getMessage(uid);
|
|
||||||
localFolder.fetch(new Message[] { message }, fp, null);
|
|
||||||
|
|
||||||
|
|
||||||
// Mark that this message is now fully synched
|
|
||||||
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
|
||||||
|
|
||||||
for (MessagingListener l : getListeners()) {
|
for (MessagingListener l : getListeners()) {
|
||||||
l.loadMessageForViewBodyAvailable(account, folder, uid, message);
|
l.loadMessageForViewBodyAvailable(account, folder, uid, message);
|
||||||
@ -1879,8 +1910,6 @@ s * critical data as fast as possible, and then we'll fill in the de
|
|||||||
for (MessagingListener l : getListeners()) {
|
for (MessagingListener l : getListeners()) {
|
||||||
l.loadMessageForViewFinished(account, folder, uid, message);
|
l.loadMessageForViewFinished(account, folder, uid, message);
|
||||||
}
|
}
|
||||||
remoteFolder.close(false);
|
|
||||||
localFolder.close(false);
|
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
for (MessagingListener l : getListeners()) {
|
for (MessagingListener l : getListeners()) {
|
||||||
@ -1889,7 +1918,26 @@ s * critical data as fast as possible, and then we'll fill in the de
|
|||||||
addErrorMessage(account, e);
|
addErrorMessage(account, e);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
finally {
|
||||||
|
if (remoteFolder!=null) {
|
||||||
|
try {
|
||||||
|
remoteFolder.close(false);
|
||||||
|
}
|
||||||
|
catch (MessagingException e) {
|
||||||
|
Log.w(Email.LOG_TAG, null, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localFolder!=null) {
|
||||||
|
try {
|
||||||
|
localFolder.close(false);
|
||||||
|
}
|
||||||
|
catch (MessagingException e) {
|
||||||
|
Log.w(Email.LOG_TAG, null, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//finally
|
||||||
|
}//run
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1905,10 +1953,6 @@ s * critical data as fast as possible, and then we'll fill in the de
|
|||||||
|
|
||||||
Message message = localFolder.getMessage(uid);
|
Message message = localFolder.getMessage(uid);
|
||||||
|
|
||||||
if (!message.isSet(Flag.SEEN)) {
|
|
||||||
markMessageRead(account, folder, uid, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (MessagingListener l : getListeners()) {
|
for (MessagingListener l : getListeners()) {
|
||||||
l.loadMessageForViewHeadersAvailable(account, folder, uid, message);
|
l.loadMessageForViewHeadersAvailable(account, folder, uid, message);
|
||||||
}
|
}
|
||||||
@ -1926,6 +1970,10 @@ s * critical data as fast as possible, and then we'll fill in the de
|
|||||||
message
|
message
|
||||||
}, fp, null);
|
}, fp, null);
|
||||||
|
|
||||||
|
if (!message.isSet(Flag.SEEN)) {
|
||||||
|
markMessageRead(account, localFolder, message, true);
|
||||||
|
}
|
||||||
|
|
||||||
for (MessagingListener l : getListeners()) {
|
for (MessagingListener l : getListeners()) {
|
||||||
l.loadMessageForViewBodyAvailable(account, folder, uid, message);
|
l.loadMessageForViewBodyAvailable(account, folder, uid, message);
|
||||||
}
|
}
|
||||||
@ -1952,6 +2000,99 @@ s * critical data as fast as possible, and then we'll fill in the de
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void loadMessageForViewSynchronous(final Account account, final String folder, final String uid,
|
||||||
|
MessagingListener listener) {
|
||||||
|
|
||||||
|
for (MessagingListener l : getListeners()) {
|
||||||
|
l.loadMessageForViewStarted(account, folder, uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalFolder localFolder = null;
|
||||||
|
Folder remoteFolder = null;
|
||||||
|
try {
|
||||||
|
Store localStore = Store.getInstance(account.getLocalStoreUri(), mApplication);
|
||||||
|
localFolder = (LocalFolder) localStore.getFolder(folder);
|
||||||
|
localFolder.open(OpenMode.READ_WRITE);
|
||||||
|
|
||||||
|
Message message = localFolder.getMessage(uid);
|
||||||
|
|
||||||
|
for (MessagingListener l : getListeners()) {
|
||||||
|
l.loadMessageForViewHeadersAvailable(account, folder, uid, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!message.isSet(Flag.X_DOWNLOADED_FULL)) {
|
||||||
|
Store remoteStore = Store.getInstance(account.getStoreUri(), mApplication);
|
||||||
|
remoteFolder = remoteStore.getFolder(folder);
|
||||||
|
remoteFolder.open(OpenMode.READ_WRITE);
|
||||||
|
|
||||||
|
// Get the remote message and fully download it
|
||||||
|
Message remoteMessage = remoteFolder.getMessage(uid);
|
||||||
|
FetchProfile fp = new FetchProfile();
|
||||||
|
fp.add(FetchProfile.Item.BODY);
|
||||||
|
remoteFolder.fetch(new Message[]{remoteMessage}, fp, null);
|
||||||
|
|
||||||
|
// Store the message locally and load the stored message into memory
|
||||||
|
localFolder.appendMessages(new Message[]{remoteMessage});
|
||||||
|
message = localFolder.getMessage(uid);
|
||||||
|
localFolder.fetch(new Message[]{message}, fp, null);
|
||||||
|
|
||||||
|
// Mark that this message is now fully synched
|
||||||
|
message.setFlag(Flag.X_DOWNLOADED_FULL, true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FetchProfile fp = new FetchProfile();
|
||||||
|
fp.add(FetchProfile.Item.ENVELOPE);
|
||||||
|
fp.add(FetchProfile.Item.BODY);
|
||||||
|
localFolder.fetch(new Message[]{
|
||||||
|
message
|
||||||
|
}, fp, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!message.isSet(Flag.SEEN)) {
|
||||||
|
markMessageRead(account, localFolder, message, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (MessagingListener l : getListeners()) {
|
||||||
|
l.loadMessageForViewBodyAvailable(account, folder, uid, message);
|
||||||
|
}
|
||||||
|
if (listener != null) {
|
||||||
|
listener.loadMessageForViewBodyAvailable(account, folder, uid, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (MessagingListener l : getListeners()) {
|
||||||
|
l.loadMessageForViewFinished(account, folder, uid, message);
|
||||||
|
}
|
||||||
|
if (listener != null) {
|
||||||
|
listener.loadMessageForViewFinished(account, folder, uid, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
for (MessagingListener l : getListeners()) {
|
||||||
|
l.loadMessageForViewFailed(account, folder, uid, e.getMessage());
|
||||||
|
}
|
||||||
|
addErrorMessage(account, e);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (localFolder!=null) {
|
||||||
|
try {
|
||||||
|
localFolder.close(false);
|
||||||
|
}
|
||||||
|
catch (MessagingException e) {
|
||||||
|
Log.w(Email.LOG_TAG, null, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remoteFolder!=null) {
|
||||||
|
try {
|
||||||
|
remoteFolder.close(false);
|
||||||
|
}
|
||||||
|
catch (MessagingException e) {
|
||||||
|
Log.w(Email.LOG_TAG, null, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}//loadMessageForViewSynchronous
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to load the attachment specified by part from the given account and message.
|
* Attempts to load the attachment specified by part from the given account and message.
|
||||||
* @param account
|
* @param account
|
||||||
|
@ -466,7 +466,7 @@ public class MessageView extends Activity
|
|||||||
// TODO this is a spot that should be eventually handled by a MessagingController
|
// TODO this is a spot that should be eventually handled by a MessagingController
|
||||||
// thread pool. We want it in a thread but it can't be blocked by the normal
|
// thread pool. We want it in a thread but it can't be blocked by the normal
|
||||||
// synchronization stuff in MC.
|
// synchronization stuff in MC.
|
||||||
MessagingController.getInstance(getApplication()).loadMessageForView(
|
MessagingController.getInstance(getApplication()).loadMessageForViewSynchronous(
|
||||||
mAccount,
|
mAccount,
|
||||||
mFolder,
|
mFolder,
|
||||||
mMessageUid,
|
mMessageUid,
|
||||||
|
Loading…
Reference in New Issue
Block a user