From 435e2c3532a590c5c31c10812508cddd23ad8013 Mon Sep 17 00:00:00 2001 From: Bao-Long Nguyen-Trong Date: Wed, 20 May 2009 04:27:51 +0000 Subject: [PATCH] Fixed issue 404: . Free up memory as we go in MessagingController.synchronizeMailboxSynchronous() . IMAP: We only do a partial fetch of the text body of large messages during background sync. This allow for faster syncs and avoid expensive parsing that lead to OutOfMemoryError --- src/com/android/email/MessagingController.java | 11 ++++++++--- src/com/android/email/mail/Store.java | 3 ++- src/com/android/email/mail/store/ImapStore.java | 8 +++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/com/android/email/MessagingController.java b/src/com/android/email/MessagingController.java index 3306ab77c..1ed49a142 100644 --- a/src/com/android/email/MessagingController.java +++ b/src/com/android/email/MessagingController.java @@ -758,6 +758,7 @@ public class MessagingController implements Runnable { if (Config.LOGV) { Log.v(Email.LOG_TAG, "SYNC: Got " + remoteUidMap.size() + " messages for folder " + folder); } + remoteMessageArray = null; /* * Get a list of the messages that are in the remote list but not on the @@ -791,7 +792,7 @@ public class MessagingController implements Runnable { /* * Fetch the flags and envelope only of the new messages. This is intended to get us -s * critical data as fast as possible, and then we'll fill in the details. + * critical data as fast as possible, and then we'll fill in the details. */ if (unsyncedMessages.size() > 0) { @@ -926,6 +927,7 @@ s * critical data as fast as possible, and then we'll fill in the de } } } + localMessages = null; /* * Now we download the actual content of messages. @@ -947,6 +949,7 @@ s * critical data as fast as possible, and then we'll fill in the de + unsyncedMessages.size() + " un synced messages " + " to fetch for folder " + folder); } + unsyncedMessages.clear(); /* @@ -997,6 +1000,7 @@ s * critical data as fast as possible, and then we'll fill in the de if (Config.LOGV) { Log.v(Email.LOG_TAG, "SYNC: Done fetching small messages for folder " + folder); } + smallMessages = null; /* * Now do the large messages that require more round trips. @@ -1077,7 +1081,7 @@ s * critical data as fast as possible, and then we'll fill in the de // Set a flag indicating this message has been fully downloaded and can be // viewed. - localMessage.setFlag(Flag.X_DOWNLOADED_FULL, true); + localMessage.setFlag(Flag.X_DOWNLOADED_PARTIAL, true); } if (isMessageSuppressed(account, folder, message) == false) { @@ -1089,10 +1093,11 @@ s * critical data as fast as possible, and then we'll fill in the de localFolder.getMessage(message.getUid())); } } - } + }//for large messsages if (Config.LOGV) { Log.v(Email.LOG_TAG, "SYNC: Done fetching large messages for folder " + folder); } + largeMessages = null; /* diff --git a/src/com/android/email/mail/Store.java b/src/com/android/email/mail/Store.java index 85edd7ceb..c0f847a2d 100644 --- a/src/com/android/email/mail/Store.java +++ b/src/com/android/email/mail/Store.java @@ -23,7 +23,8 @@ public abstract class Store { * A global suggestion to Store implementors on how much of the body * should be returned on FetchProfile.Item.BODY_SANE requests. */ - public static final int FETCH_BODY_SANE_SUGGESTED_SIZE = (50 * 1024); + //Matching MessagingController.MAX_SMALL_MESSAGE_SIZE + public static final int FETCH_BODY_SANE_SUGGESTED_SIZE = (5 * 1024); protected static final int SOCKET_CONNECT_TIMEOUT = 10000; protected static final int SOCKET_READ_TIMEOUT = 60000; diff --git a/src/com/android/email/mail/store/ImapStore.java b/src/com/android/email/mail/store/ImapStore.java index cb46a645b..defcc7268 100644 --- a/src/com/android/email/mail/store/ImapStore.java +++ b/src/com/android/email/mail/store/ImapStore.java @@ -738,7 +738,12 @@ public class ImapStore extends Store { if (o instanceof Part) { Part part = (Part) o; String partId = part.getHeader(MimeHeader.HEADER_ANDROID_ATTACHMENT_STORE_DATA)[0]; - fetchFields.add("BODY.PEEK[" + partId + "]"); + if ("TEXT".equals(partId)) { + fetchFields.add(String.format("BODY.PEEK[TEXT]<0.%d>", FETCH_BODY_SANE_SUGGESTED_SIZE)); + } + else { + fetchFields.add("BODY.PEEK[" + partId + "]"); + } } } @@ -1457,6 +1462,7 @@ public class ImapStore extends Store { open(); String tag = Integer.toString(mNextCommandTag++); String commandToSend = tag + " " + command; + Log.v(Email.LOG_TAG, commandToSend); mOut.write(commandToSend.getBytes()); mOut.write('\r'); mOut.write('\n');