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 State currentState = null;
private class State {
private Context context; private Context context;
private long fid; private long fid;
private String search; private String search;
private int pageSize; private int pageSize;
private int local = 0; int local = 0;
private List<Long> messages = null; List<Long> messages = null;
private IMAPStore istore = null; IMAPStore istore = null;
private IMAPFolder ifolder = null; IMAPFolder ifolder = null;
private Message[] imessages = null; Message[] imessages = null;
private int index = -1; int index = -1;
void set(Context context, long folder, String search, int pageSize) {
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;
} }
} }
} }