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 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.<Plaintext>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();

View File

@ -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) {

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
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)));