Asynchronously load messages to improve responsiveness

This commit is contained in:
Christian Basler 2017-06-30 00:07:54 +02:00
parent bf52d2f3de
commit 1c284eba26
3 changed files with 69 additions and 20 deletions

View File

@ -39,12 +39,14 @@ import com.h6ah4i.android.widget.advrecyclerview.touchguard.RecyclerViewTouchAct
import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils; import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import ch.dissem.apps.abit.adapter.SwipeableMessageAdapter; import ch.dissem.apps.abit.adapter.SwipeableMessageAdapter;
import ch.dissem.apps.abit.listener.ActionBarListener; import ch.dissem.apps.abit.listener.ActionBarListener;
import ch.dissem.apps.abit.listener.ListSelectionListener; import ch.dissem.apps.abit.listener.ListSelectionListener;
import ch.dissem.apps.abit.repository.AndroidMessageRepository;
import ch.dissem.apps.abit.service.Singleton; import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.bitmessage.entity.BitmessageAddress; import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.entity.Plaintext; import ch.dissem.bitmessage.entity.Plaintext;
@ -77,7 +79,7 @@ public class MessageListFragment extends Fragment implements ListHolder {
private Label currentLabel; private Label currentLabel;
private MenuItem emptyTrashMenuItem; private MenuItem emptyTrashMenuItem;
private MessageRepository messageRepo; private AndroidMessageRepository messageRepo;
private boolean activateOnItemClick; private boolean activateOnItemClick;
@Override @Override
@ -103,19 +105,15 @@ public class MessageListFragment extends Fragment implements ListHolder {
return; return;
} }
if (!Objects.equals(currentLabel, label)) {
adapter.setData(label, Collections.<Plaintext>emptyList());
adapter.notifyDataSetChanged();
}
doUpdateList(label); doUpdateList(label);
} }
private void doUpdateList(final Label label) { private void doUpdateList(final Label label) {
adapter.clear(label);
if (label == null) { if (label == null) {
if (getActivity() instanceof ActionBarListener) { if (getActivity() instanceof ActionBarListener) {
((ActionBarListener) getActivity()).updateTitle(getString(R.string.app_name)); ((ActionBarListener) getActivity()).updateTitle(getString(R.string.app_name));
} }
adapter.setData(null, Collections.<Plaintext>emptyList());
adapter.notifyDataSetChanged(); adapter.notifyDataSetChanged();
return; return;
} }
@ -131,18 +129,24 @@ public class MessageListFragment extends Fragment implements ListHolder {
actionBarListener.updateTitle(label.toString()); actionBarListener.updateTitle(label.toString());
} }
} }
new AsyncTask<Void, Void, List<Plaintext>>() {
new AsyncTask<Void, Plaintext, Void>() {
@Override @Override
protected List<Plaintext> doInBackground(Void... params) { protected Void doInBackground(Void... params) {
return messageRepo.findMessages(label); List<Long> ids = messageRepo.findMessageIds(label);
for (Long id : ids) {
Plaintext message = messageRepo.getMessage(id);
publishProgress(message);
}
return null;
} }
@Override @Override
protected void onPostExecute(List<Plaintext> messages) { protected void onProgressUpdate(Plaintext... values) {
if (adapter != null) { if (adapter != null) {
adapter.setData(label, messages); for (Plaintext message : values) {
adapter.notifyDataSetChanged(); adapter.add(message);
}
} }
} }
}.execute(); }.execute();

View File

@ -37,6 +37,7 @@ import com.h6ah4i.android.widget.advrecyclerview.utils.AbstractSwipeableItemView
import com.h6ah4i.android.widget.advrecyclerview.utils.RecyclerViewAdapterUtils; import com.h6ah4i.android.widget.advrecyclerview.utils.RecyclerViewAdapterUtils;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import ch.dissem.apps.abit.Identicon; import ch.dissem.apps.abit.Identicon;
@ -59,7 +60,7 @@ public class SwipeableMessageAdapter
extends RecyclerView.Adapter<SwipeableMessageAdapter.ViewHolder> extends RecyclerView.Adapter<SwipeableMessageAdapter.ViewHolder>
implements SwipeableItemAdapter<SwipeableMessageAdapter.ViewHolder>, SwipeableItemConstants { implements SwipeableItemAdapter<SwipeableMessageAdapter.ViewHolder>, SwipeableItemConstants {
private List<Plaintext> data = Collections.emptyList(); private List<Plaintext> data = new LinkedList<>();
private EventListener eventListener; private EventListener eventListener;
private final View.OnClickListener itemViewOnClickListener; private final View.OnClickListener itemViewOnClickListener;
private final View.OnClickListener swipeableViewContainerOnClickListener; private final View.OnClickListener swipeableViewContainerOnClickListener;
@ -124,9 +125,15 @@ public class SwipeableMessageAdapter
setHasStableIds(true); setHasStableIds(true);
} }
public void setData(Label label, List<Plaintext> data) { public void add(Plaintext item) {
this.label = label; data.add(item);
this.data = data; notifyDataSetChanged();
}
public void clear(Label newLabel) {
label = newLabel;
data.clear();
notifyDataSetChanged();
} }
private void onItemViewClick(View v) { private void onItemViewClick(View v) {

View File

@ -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 @NonNull
public List<Label> findLabels(String where) { public List<Label> findLabels(String where) {
List<Label> result = new LinkedList<>(); List<Label> result = new LinkedList<>();
@ -239,6 +248,31 @@ public class AndroidMessageRepository extends AbstractMessageRepository {
db.update(PARENTS_TABLE_NAME, values, "conversation=?", whereArgs); 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 @NonNull
protected List<Plaintext> find(String where) { protected List<Plaintext> find(String where) {
List<Plaintext> result = new LinkedList<>(); List<Plaintext> result = new LinkedList<>();
@ -279,10 +313,14 @@ public class AndroidMessageRepository extends AbstractMessageRepository {
long id = c.getLong(c.getColumnIndex(COLUMN_ID)); long id = c.getLong(c.getColumnIndex(COLUMN_ID));
builder.id(id); builder.id(id);
builder.IV(InventoryVector.fromHash(iv)); builder.IV(InventoryVector.fromHash(iv));
builder.from(ctx.getAddressRepository().getAddress(c.getString(c.getColumnIndex String sender = c.getString(c.getColumnIndex(COLUMN_SENDER));
(COLUMN_SENDER)))); if (sender != null) {
builder.to(ctx.getAddressRepository().getAddress(c.getString(c.getColumnIndex builder.from(ctx.getAddressRepository().getAddress(sender));
(COLUMN_RECIPIENT)))); }
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.ackData(c.getBlob(c.getColumnIndex(COLUMN_ACK_DATA)));
builder.sent(c.getLong(c.getColumnIndex(COLUMN_SENT))); builder.sent(c.getLong(c.getColumnIndex(COLUMN_SENT)));
builder.received(c.getLong(c.getColumnIndex(COLUMN_RECEIVED))); builder.received(c.getLong(c.getColumnIndex(COLUMN_RECEIVED)));