From 1c284eba26d02404a12a973bbac7f3ac30594bc0 Mon Sep 17 00:00:00 2001 From: Christian Basler Date: Fri, 30 Jun 2017 00:07:54 +0200 Subject: [PATCH] Asynchronously load messages to improve responsiveness --- .../dissem/apps/abit/MessageListFragment.java | 28 ++++++----- .../abit/adapter/SwipeableMessageAdapter.java | 15 ++++-- .../repository/AndroidMessageRepository.java | 46 +++++++++++++++++-- 3 files changed, 69 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/ch/dissem/apps/abit/MessageListFragment.java b/app/src/main/java/ch/dissem/apps/abit/MessageListFragment.java index 5d43314..e3a187a 100644 --- a/app/src/main/java/ch/dissem/apps/abit/MessageListFragment.java +++ b/app/src/main/java/ch/dissem/apps/abit/MessageListFragment.java @@ -39,12 +39,14 @@ import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchAct import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Objects; import ch.dissem.apps.abit.adapter.SwipeableMessageAdapter; import ch.dissem.apps.abit.listener.ActionBarListener; import ch.dissem.apps.abit.listener.ListSelectionListener; +import ch.dissem.apps.abit.repository.AndroidMessageRepository; import ch.dissem.apps.abit.service.Singleton; import ch.dissem.bitmessage.entity.BitmessageAddress; import ch.dissem.bitmessage.entity.Plaintext; @@ -77,7 +79,7 @@ public class MessageListFragment extends Fragment implements ListHolder { private Label currentLabel; private MenuItem emptyTrashMenuItem; - private MessageRepository messageRepo; + private AndroidMessageRepository messageRepo; private boolean activateOnItemClick; @Override @@ -103,19 +105,15 @@ public class MessageListFragment extends Fragment implements ListHolder { return; } - if (!Objects.equals(currentLabel, label)) { - adapter.setData(label, Collections.emptyList()); - adapter.notifyDataSetChanged(); - } doUpdateList(label); } private void doUpdateList(final Label label) { + adapter.clear(label); if (label == null) { if (getActivity() instanceof ActionBarListener) { ((ActionBarListener) getActivity()).updateTitle(getString(R.string.app_name)); } - adapter.setData(null, Collections.<Plaintext>emptyList()); adapter.notifyDataSetChanged(); return; } @@ -131,18 +129,24 @@ public class MessageListFragment extends Fragment implements ListHolder { actionBarListener.updateTitle(label.toString()); } } - new AsyncTask<Void, Void, List<Plaintext>>() { + new AsyncTask<Void, Plaintext, Void>() { @Override - protected List<Plaintext> doInBackground(Void... params) { - return messageRepo.findMessages(label); + protected Void doInBackground(Void... params) { + List<Long> ids = messageRepo.findMessageIds(label); + for (Long id : ids) { + Plaintext message = messageRepo.getMessage(id); + publishProgress(message); + } + return null; } @Override - protected void onPostExecute(List<Plaintext> messages) { + protected void onProgressUpdate(Plaintext... values) { if (adapter != null) { - adapter.setData(label, messages); - adapter.notifyDataSetChanged(); + for (Plaintext message : values) { + adapter.add(message); + } } } }.execute(); diff --git a/app/src/main/java/ch/dissem/apps/abit/adapter/SwipeableMessageAdapter.java b/app/src/main/java/ch/dissem/apps/abit/adapter/SwipeableMessageAdapter.java index 070092f..df3e2c0 100644 --- a/app/src/main/java/ch/dissem/apps/abit/adapter/SwipeableMessageAdapter.java +++ b/app/src/main/java/ch/dissem/apps/abit/adapter/SwipeableMessageAdapter.java @@ -37,6 +37,7 @@ import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractSwipeableItemView import com.h6ah4i.android.widget.advrecyclerview.utils.RecyclerViewAdapterUtils; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import ch.dissem.apps.abit.Identicon; @@ -59,7 +60,7 @@ public class SwipeableMessageAdapter extends RecyclerView.Adapter<SwipeableMessageAdapter.ViewHolder> implements SwipeableItemAdapter<SwipeableMessageAdapter.ViewHolder>, SwipeableItemConstants { - private List<Plaintext> data = Collections.emptyList(); + private List<Plaintext> data = new LinkedList<>(); private EventListener eventListener; private final View.OnClickListener itemViewOnClickListener; private final View.OnClickListener swipeableViewContainerOnClickListener; @@ -124,9 +125,15 @@ public class SwipeableMessageAdapter setHasStableIds(true); } - public void setData(Label label, List<Plaintext> data) { - this.label = label; - this.data = data; + public void add(Plaintext item) { + data.add(item); + notifyDataSetChanged(); + } + + public void clear(Label newLabel) { + label = newLabel; + data.clear(); + notifyDataSetChanged(); } private void onItemViewClick(View v) { diff --git a/app/src/main/java/ch/dissem/apps/abit/repository/AndroidMessageRepository.java b/app/src/main/java/ch/dissem/apps/abit/repository/AndroidMessageRepository.java index b62e761..316f5f8 100644 --- a/app/src/main/java/ch/dissem/apps/abit/repository/AndroidMessageRepository.java +++ b/app/src/main/java/ch/dissem/apps/abit/repository/AndroidMessageRepository.java @@ -101,6 +101,15 @@ public class AndroidMessageRepository extends AbstractMessageRepository { } } + @NonNull + public List<Long> findMessageIds(Label label) { + if (label == LABEL_ARCHIVE) { + return findIds("id NOT IN (SELECT message_id FROM Message_Label)"); + } else { + return findIds("id IN (SELECT message_id FROM Message_Label WHERE label_id=" + label.getId() + ")"); + } + } + @NonNull public List<Label> findLabels(String where) { List<Label> result = new LinkedList<>(); @@ -239,6 +248,31 @@ public class AndroidMessageRepository extends AbstractMessageRepository { db.update(PARENTS_TABLE_NAME, values, "conversation=?", whereArgs); } + @NonNull + protected List<Long> findIds(String where) { + List<Long> result = new LinkedList<>(); + + // Define a projection that specifies which columns from the database + // you will actually use after this query. + String[] projection = { + COLUMN_ID + }; + + SQLiteDatabase db = sql.getReadableDatabase(); + try (Cursor c = db.query( + TABLE_NAME, projection, + where, + null, null, null, + COLUMN_RECEIVED + " DESC, " + COLUMN_SENT + " DESC" + )) { + while (c.moveToNext()) { + long id = c.getLong(c.getColumnIndex(COLUMN_ID)); + result.add(id); + } + } + return result; + } + @NonNull protected List<Plaintext> find(String where) { List<Plaintext> result = new LinkedList<>(); @@ -279,10 +313,14 @@ public class AndroidMessageRepository extends AbstractMessageRepository { long id = c.getLong(c.getColumnIndex(COLUMN_ID)); builder.id(id); builder.IV(InventoryVector.fromHash(iv)); - builder.from(ctx.getAddressRepository().getAddress(c.getString(c.getColumnIndex - (COLUMN_SENDER)))); - builder.to(ctx.getAddressRepository().getAddress(c.getString(c.getColumnIndex - (COLUMN_RECIPIENT)))); + String sender = c.getString(c.getColumnIndex(COLUMN_SENDER)); + if (sender != null) { + builder.from(ctx.getAddressRepository().getAddress(sender)); + } + String recipient = c.getString(c.getColumnIndex(COLUMN_RECIPIENT)); + if (recipient != null) { + builder.to(ctx.getAddressRepository().getAddress(recipient)); + } builder.ackData(c.getBlob(c.getColumnIndex(COLUMN_ACK_DATA))); builder.sent(c.getLong(c.getColumnIndex(COLUMN_SENT))); builder.received(c.getLong(c.getColumnIndex(COLUMN_RECEIVED)));