Prevent crash

This commit is contained in:
M66B 2018-11-14 07:39:17 +01:00
parent 6f98929d72
commit 172a1851fd
1 changed files with 72 additions and 67 deletions

View File

@ -49,55 +49,55 @@ import javax.mail.search.SubjectTerm;
import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
public class ViewModelBrowse extends ViewModel { public class ViewModelBrowse extends ViewModel {
private Context context; private State currentState = null;
private long fid;
private String search;
private int pageSize;
private int local = 0; private class State {
private List<Long> messages = null; private Context context;
private IMAPStore istore = null; private long fid;
private IMAPFolder ifolder = null; private String search;
private Message[] imessages = null; private int pageSize;
private int index = -1; int local = 0;
List<Long> messages = null;
IMAPStore istore = null;
IMAPFolder ifolder = null;
Message[] imessages = null;
void set(Context context, long folder, String search, int pageSize) { int index = -1;
this.context = context;
this.fid = folder;
this.search = search;
this.pageSize = pageSize;
this.index = -1;
} }
@Override void set(Context context, long folder, String search, int pageSize) {
protected void onCleared() { currentState = new State();
context = null; currentState.context = context;
istore = null; currentState.fid = folder;
ifolder = null; currentState.search = search;
imessages = null; currentState.pageSize = pageSize;
currentState.index = -1;
} }
void load() throws MessagingException, IOException { void load() throws MessagingException, IOException {
DB db = DB.getInstance(context); State state = currentState;
EntityFolder folder = db.folder().getFolder(fid); if (state == null)
return;
if (search != null) DB db = DB.getInstance(state.context);
EntityFolder folder = db.folder().getFolder(state.fid);
if (state.search != null)
try { try {
db.beginTransaction(); db.beginTransaction();
if (messages == null) if (state.messages == null)
messages = db.message().getMessageByFolder(fid); state.messages = db.message().getMessageByFolder(state.fid);
int matched = 0; int matched = 0;
for (int i = local; i < messages.size() && matched < pageSize; i++) { for (int i = state.local; i < state.messages.size() && matched < state.pageSize; i++) {
local = i + 1; state.local = i + 1;
boolean match = false; boolean match = false;
String find = search.toLowerCase(); String find = state.search.toLowerCase();
EntityMessage message = db.message().getMessage(messages.get(i)); EntityMessage message = db.message().getMessage(state.messages.get(i));
String body = (message.content ? message.read(context) : null); String body = (message.content ? message.read(state.context) : null);
if (message.from != null) if (message.from != null)
for (int j = 0; j < message.from.length && !match; j++) for (int j = 0; j < message.from.length && !match; j++)
@ -119,19 +119,19 @@ public class ViewModelBrowse extends ViewModel {
message.ui_found = true; message.ui_found = true;
message.id = db.message().insertMessage(message); message.id = db.message().insertMessage(message);
if (message.content) if (message.content)
message.write(context, body); message.write(state.context, body);
} }
} }
db.setTransactionSuccessful(); db.setTransactionSuccessful();
if (++matched >= pageSize) if (++matched >= state.pageSize)
return; return;
} finally { } finally {
db.endTransaction(); db.endTransaction();
} }
if (imessages == null) { if (state.imessages == null) {
if (folder.account == null) // outbox if (folder.account == null) // outbox
return; return;
@ -142,40 +142,40 @@ public class ViewModelBrowse extends ViewModel {
Session isession = Session.getInstance(props, null); Session isession = Session.getInstance(props, null);
Log.i(Helper.TAG, "Boundary connecting account=" + account.name); Log.i(Helper.TAG, "Boundary connecting account=" + account.name);
istore = (IMAPStore) isession.getStore(account.starttls ? "imap" : "imaps"); state.istore = (IMAPStore) isession.getStore(account.starttls ? "imap" : "imaps");
Helper.connect(context, istore, account); Helper.connect(state.context, state.istore, account);
Log.i(Helper.TAG, "Boundary opening folder=" + folder.name); Log.i(Helper.TAG, "Boundary opening folder=" + folder.name);
ifolder = (IMAPFolder) istore.getFolder(folder.name); state.ifolder = (IMAPFolder) state.istore.getFolder(folder.name);
ifolder.open(Folder.READ_WRITE); state.ifolder.open(Folder.READ_WRITE);
Log.i(Helper.TAG, "Boundary searching=" + search); Log.i(Helper.TAG, "Boundary searching=" + state.search);
if (search == null) if (state.search == null)
imessages = ifolder.getMessages(); state.imessages = state.ifolder.getMessages();
else else
imessages = ifolder.search( state.imessages = state.ifolder.search(
new OrTerm( new OrTerm(
new OrTerm( new OrTerm(
new FromStringTerm(search), new FromStringTerm(state.search),
new RecipientStringTerm(Message.RecipientType.TO, search) new RecipientStringTerm(Message.RecipientType.TO, state.search)
), ),
new OrTerm( new OrTerm(
new SubjectTerm(search), new SubjectTerm(state.search),
new BodyTerm(search) new BodyTerm(state.search)
) )
) )
); );
Log.i(Helper.TAG, "Boundary found messages=" + imessages.length); Log.i(Helper.TAG, "Boundary found messages=" + state.imessages.length);
index = imessages.length - 1; state.index = state.imessages.length - 1;
} }
int count = 0; int count = 0;
while (index >= 0 && count < pageSize) { while (state.index >= 0 && count < state.pageSize && currentState != null) {
Log.i(Helper.TAG, "Boundary index=" + index); Log.i(Helper.TAG, "Boundary index=" + state.index);
int from = Math.max(0, index - (pageSize - count) + 1); int from = Math.max(0, state.index - (state.pageSize - count) + 1);
Message[] isub = Arrays.copyOfRange(imessages, from, index + 1); Message[] isub = Arrays.copyOfRange(state.imessages, from, state.index + 1);
index -= (pageSize - count); state.index -= (state.pageSize - count);
FetchProfile fp = new FetchProfile(); FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE); fp.add(FetchProfile.Item.ENVELOPE);
@ -185,18 +185,19 @@ public class ViewModelBrowse extends ViewModel {
fp.add(IMAPFolder.FetchProfileItem.HEADERS); fp.add(IMAPFolder.FetchProfileItem.HEADERS);
fp.add(FetchProfile.Item.SIZE); fp.add(FetchProfile.Item.SIZE);
fp.add(IMAPFolder.FetchProfileItem.INTERNALDATE); fp.add(IMAPFolder.FetchProfileItem.INTERNALDATE);
ifolder.fetch(isub, fp); state.ifolder.fetch(isub, fp);
try { try {
db.beginTransaction(); db.beginTransaction();
for (int j = isub.length - 1; j >= 0; j--) for (int j = isub.length - 1; j >= 0; j--)
try { try {
long uid = ifolder.getUID(isub[j]); long uid = state.ifolder.getUID(isub[j]);
Log.i(Helper.TAG, "Boundary sync uid=" + uid); Log.i(Helper.TAG, "Boundary sync uid=" + uid);
EntityMessage message = db.message().getMessageByUid(fid, uid, search != null); EntityMessage message = db.message().getMessageByUid(state.fid, uid, state.search != null);
if (message == null) { if (message == null) {
ServiceSynchronize.synchronizeMessage(context, folder, ifolder, (IMAPMessage) isub[j], search != null); ServiceSynchronize.synchronizeMessage(
state.context, folder, state.ifolder, (IMAPMessage) isub[j], state.search != null);
count++; count++;
} }
} catch (MessageRemovedException ex) { } catch (MessageRemovedException ex) {
@ -221,19 +222,23 @@ public class ViewModelBrowse extends ViewModel {
} }
void clear() { void clear() {
State state = currentState;
if (state == null)
return;
currentState = null;
Log.i(Helper.TAG, "Boundary clear"); Log.i(Helper.TAG, "Boundary clear");
try { try {
if (istore != null) if (state.istore != null)
istore.close(); state.istore.close();
} catch (Throwable ex) { } catch (Throwable ex) {
Log.e(Helper.TAG, "Boundary " + ex + "\n" + Log.getStackTraceString(ex)); Log.e(Helper.TAG, "Boundary " + ex + "\n" + Log.getStackTraceString(ex));
} finally { } finally {
context = null; state.context = null;
local = 0; state.messages = null;
messages = null; state.istore = null;
istore = null; state.ifolder = null;
ifolder = null; state.imessages = null;
imessages = null;
} }
} }
} }