use Loader when conversation is updated instead of requery

// FREEBIE
This commit is contained in:
Jake McGinty 2014-09-24 13:54:56 -07:00
parent f3f173f653
commit a88fbba49f
6 changed files with 108 additions and 23 deletions

View File

@ -65,7 +65,7 @@ public class ConversationAdapter extends CursorAdapter implements AbsListView.Re
public ConversationAdapter(Context context, MasterSecret masterSecret, public ConversationAdapter(Context context, MasterSecret masterSecret,
Handler failedIconClickHandler, boolean groupThread, boolean pushDestination) Handler failedIconClickHandler, boolean groupThread, boolean pushDestination)
{ {
super(context, null, true); super(context, null, 0);
this.context = context; this.context = context;
this.masterSecret = masterSecret; this.masterSecret = masterSecret;
this.failedIconClickHandler = failedIconClickHandler; this.failedIconClickHandler = failedIconClickHandler;
@ -84,6 +84,12 @@ public class ConversationAdapter extends CursorAdapter implements AbsListView.Re
item.set(masterSecret, messageRecord, failedIconClickHandler, groupThread, pushDestination); item.set(masterSecret, messageRecord, failedIconClickHandler, groupThread, pushDestination);
} }
@Override
public void changeCursor(Cursor cursor) {
messageRecordCache.clear();
super.changeCursor(cursor);
}
@Override @Override
public View newView(Context context, Cursor cursor, ViewGroup parent) { public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view; View view;
@ -148,12 +154,6 @@ public class ConversationAdapter extends CursorAdapter implements AbsListView.Re
return messageRecord; return messageRecord;
} }
@Override
protected void onContentChanged() {
super.onContentChanged();
messageRecordCache.clear();
}
public void close() { public void close() {
this.getCursor().close(); this.getCursor().close();
} }

View File

@ -18,11 +18,11 @@ package org.thoughtcrime.securesms;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AbsListView; import android.widget.AbsListView;
import android.widget.CursorAdapter;
import org.thoughtcrime.securesms.crypto.MasterCipher; import org.thoughtcrime.securesms.crypto.MasterCipher;
import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.crypto.MasterSecret;
@ -50,7 +50,7 @@ public class ConversationListAdapter extends CursorAdapter implements AbsListVie
private boolean batchMode = false; private boolean batchMode = false;
public ConversationListAdapter(Context context, Cursor cursor, MasterSecret masterSecret) { public ConversationListAdapter(Context context, Cursor cursor, MasterSecret masterSecret) {
super(context, cursor); super(context, cursor, 0);
if (masterSecret != null) this.masterCipher = new MasterCipher(masterSecret); if (masterSecret != null) this.masterCipher = new MasterCipher(masterSecret);
else this.masterCipher = null; else this.masterCipher = null;

View File

@ -32,6 +32,7 @@ import android.support.v7.app.ActionBarActivity;
import android.support.v7.view.ActionMode; import android.support.v7.view.ActionMode;
import android.support.v7.widget.SearchView; import android.support.v7.widget.SearchView;
import android.util.Log; import android.util.Log;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -39,7 +40,6 @@ import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.CursorAdapter;
import android.widget.ListView; import android.widget.ListView;
import org.thoughtcrime.securesms.components.DefaultSmsReminder; import org.thoughtcrime.securesms.components.DefaultSmsReminder;

View File

@ -2,26 +2,24 @@ package org.thoughtcrime.securesms.database.loaders;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.support.v4.content.CursorLoader;
import org.thoughtcrime.securesms.contacts.ContactAccessor; import org.thoughtcrime.securesms.contacts.ContactAccessor;
import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.util.AbstractCursorLoader;
import java.util.List; import java.util.List;
public class ConversationListLoader extends CursorLoader { public class ConversationListLoader extends AbstractCursorLoader {
private final String filter; private final String filter;
private final Context context;
public ConversationListLoader(Context context, String filter) { public ConversationListLoader(Context context, String filter) {
super(context); super(context);
this.filter = filter; this.filter = filter;
this.context = context.getApplicationContext();
} }
@Override @Override
public Cursor loadInBackground() { public Cursor getCursor() {
if (filter != null && filter.trim().length() != 0) { if (filter != null && filter.trim().length() != 0) {
List<String> numbers = ContactAccessor.getInstance() List<String> numbers = ContactAccessor.getInstance()
.getNumbersForThreadSearchFilter(filter, context.getContentResolver()); .getNumbersForThreadSearchFilter(filter, context.getContentResolver());

View File

@ -2,23 +2,20 @@ package org.thoughtcrime.securesms.database.loaders;
import android.content.Context; import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.support.v4.content.CursorLoader;
import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.util.AbstractCursorLoader;
public class ConversationLoader extends CursorLoader { public class ConversationLoader extends AbstractCursorLoader {
private final long threadId;
private final Context context;
private final long threadId;
public ConversationLoader(Context context, long threadId) { public ConversationLoader(Context context, long threadId) {
super(context); super(context);
this.context = context.getApplicationContext();
this.threadId = threadId; this.threadId = threadId;
} }
@Override @Override
public Cursor loadInBackground() { public Cursor getCursor() {
return DatabaseFactory.getMmsSmsDatabase(context).getConversation(threadId); return DatabaseFactory.getMmsSmsDatabase(context).getConversation(threadId);
} }
} }

View File

@ -0,0 +1,90 @@
package org.thoughtcrime.securesms.util;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.content.AsyncTaskLoader;
/**
* A Loader similar to CursorLoader that doesn't require queries to go through the ContentResolver
* to get the benefits of reloading when content has changed.
*/
public abstract class AbstractCursorLoader extends AsyncTaskLoader<Cursor> {
private static final String TAG = AbstractCursorLoader.class.getSimpleName();
protected final ForceLoadContentObserver observer;
protected final Context context;
protected Cursor cursor;
public AbstractCursorLoader(Context context) {
super(context);
this.context = context.getApplicationContext();
this.observer = new ForceLoadContentObserver();
}
public abstract Cursor getCursor();
@Override
public void deliverResult(Cursor newCursor) {
if (isReset()) {
if (newCursor != null) {
newCursor.close();
}
return;
}
Cursor oldCursor = this.cursor;
this.cursor = newCursor;
if (isStarted()) {
super.deliverResult(newCursor);
}
if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {
oldCursor.close();
}
}
@Override
protected void onStartLoading() {
if (cursor != null) {
deliverResult(cursor);
}
if (takeContentChanged() || cursor == null) {
forceLoad();
}
}
@Override
protected void onStopLoading() {
cancelLoad();
}
@Override
public void onCanceled(Cursor cursor) {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
@Override
public Cursor loadInBackground() {
Cursor newCursor = getCursor();
if (newCursor != null) {
newCursor.getCount();
newCursor.registerContentObserver(observer);
}
return newCursor;
}
@Override
protected void onReset() {
super.onReset();
onStopLoading();
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
cursor = null;
}
}