mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-30 13:35:18 +00:00
Don't blow away entire recipient cache on clear event.
Switch to marking recipients as "dirty" instead. // FREEBIE
This commit is contained in:
parent
73bc7220db
commit
f7e34a707d
@ -212,8 +212,7 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
|||||||
@Override
|
@Override
|
||||||
public void onChange(boolean selfChange) {
|
public void onChange(boolean selfChange) {
|
||||||
super.onChange(selfChange);
|
super.onChange(selfChange);
|
||||||
Log.w(TAG, "detected android contact data changed, refreshing cache");
|
Log.w(TAG, "Detected android contact data changed, refreshing cache");
|
||||||
// TODO only clear updated recipients from cache
|
|
||||||
RecipientFactory.clearCache();
|
RecipientFactory.clearCache();
|
||||||
ConversationListActivity.this.runOnUiThread(new Runnable() {
|
ConversationListActivity.this.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -45,19 +45,30 @@ public class Recipient {
|
|||||||
|
|
||||||
private String number;
|
private String number;
|
||||||
private String name;
|
private String name;
|
||||||
|
private boolean stale;
|
||||||
|
|
||||||
private ContactPhoto contactPhoto;
|
private ContactPhoto contactPhoto;
|
||||||
private Uri contactUri;
|
private Uri contactUri;
|
||||||
|
|
||||||
@Nullable private MaterialColor color;
|
@Nullable private MaterialColor color;
|
||||||
|
|
||||||
Recipient(long recipientId, String number, ListenableFutureTask<RecipientDetails> future)
|
Recipient(long recipientId,
|
||||||
|
@NonNull String number,
|
||||||
|
@Nullable Recipient stale,
|
||||||
|
@NonNull ListenableFutureTask<RecipientDetails> future)
|
||||||
{
|
{
|
||||||
this.recipientId = recipientId;
|
this.recipientId = recipientId;
|
||||||
this.number = number;
|
this.number = number;
|
||||||
this.contactPhoto = ContactPhotoFactory.getLoadingPhoto();
|
this.contactPhoto = ContactPhotoFactory.getLoadingPhoto();
|
||||||
this.color = null;
|
this.color = null;
|
||||||
|
|
||||||
|
if (stale != null) {
|
||||||
|
this.name = stale.name;
|
||||||
|
this.contactUri = stale.contactUri;
|
||||||
|
this.contactPhoto = stale.contactPhoto;
|
||||||
|
this.color = stale.color;
|
||||||
|
}
|
||||||
|
|
||||||
future.addListener(new FutureTaskListener<RecipientDetails>() {
|
future.addListener(new FutureTaskListener<RecipientDetails>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(RecipientDetails result) {
|
public void onSuccess(RecipientDetails result) {
|
||||||
@ -76,7 +87,7 @@ public class Recipient {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable error) {
|
public void onFailure(Throwable error) {
|
||||||
Log.w("Recipient", error);
|
Log.w(TAG, error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -174,4 +185,12 @@ public class Recipient {
|
|||||||
public interface RecipientModifiedListener {
|
public interface RecipientModifiedListener {
|
||||||
public void onModified(Recipient recipient);
|
public void onModified(Recipient recipient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isStale() {
|
||||||
|
return stale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setStale() {
|
||||||
|
this.stale = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,8 @@ public class RecipientProvider {
|
|||||||
|
|
||||||
private static final String TAG = RecipientProvider.class.getSimpleName();
|
private static final String TAG = RecipientProvider.class.getSimpleName();
|
||||||
|
|
||||||
private static final Map<Long,Recipient> recipientCache = Collections.synchronizedMap(new LRUCache<Long,Recipient>(1000));
|
private static final RecipientCache recipientCache = new RecipientCache();
|
||||||
private static final Map<RecipientIds,Recipients> recipientsCache = Collections.synchronizedMap(new LRUCache<RecipientIds, Recipients>(1000));
|
private static final RecipientsCache recipientsCache = new RecipientsCache();
|
||||||
private static final ExecutorService asyncRecipientResolver = Util.newSingleThreadedLifoExecutor();
|
private static final ExecutorService asyncRecipientResolver = Util.newSingleThreadedLifoExecutor();
|
||||||
|
|
||||||
private static final String[] CALLER_ID_PROJECTION = new String[] {
|
private static final String[] CALLER_ID_PROJECTION = new String[] {
|
||||||
@ -64,23 +64,23 @@ public class RecipientProvider {
|
|||||||
|
|
||||||
Recipient getRecipient(Context context, long recipientId, boolean asynchronous) {
|
Recipient getRecipient(Context context, long recipientId, boolean asynchronous) {
|
||||||
Recipient cachedRecipient = recipientCache.get(recipientId);
|
Recipient cachedRecipient = recipientCache.get(recipientId);
|
||||||
if (cachedRecipient != null) return cachedRecipient;
|
if (cachedRecipient != null && !cachedRecipient.isStale()) return cachedRecipient;
|
||||||
|
|
||||||
String number = CanonicalAddressDatabase.getInstance(context).getAddressFromId(recipientId);
|
String number = CanonicalAddressDatabase.getInstance(context).getAddressFromId(recipientId);
|
||||||
|
|
||||||
if (asynchronous) {
|
if (asynchronous) {
|
||||||
cachedRecipient = new Recipient(recipientId, number, getRecipientDetailsAsync(context, recipientId, number));
|
cachedRecipient = new Recipient(recipientId, number, cachedRecipient, getRecipientDetailsAsync(context, recipientId, number));
|
||||||
} else {
|
} else {
|
||||||
cachedRecipient = new Recipient(recipientId, getRecipientDetailsSync(context, recipientId, number));
|
cachedRecipient = new Recipient(recipientId, getRecipientDetailsSync(context, recipientId, number));
|
||||||
}
|
}
|
||||||
|
|
||||||
recipientCache.put(recipientId, cachedRecipient);
|
recipientCache.set(recipientId, cachedRecipient);
|
||||||
return cachedRecipient;
|
return cachedRecipient;
|
||||||
}
|
}
|
||||||
|
|
||||||
Recipients getRecipients(Context context, long[] recipientIds, boolean asynchronous) {
|
Recipients getRecipients(Context context, long[] recipientIds, boolean asynchronous) {
|
||||||
Recipients cachedRecipients = recipientsCache.get(new RecipientIds(recipientIds));
|
Recipients cachedRecipients = recipientsCache.get(new RecipientIds(recipientIds));
|
||||||
if (cachedRecipients != null) return cachedRecipients;
|
if (cachedRecipients != null && !cachedRecipients.isStale()) return cachedRecipients;
|
||||||
|
|
||||||
List<Recipient> recipientList = new LinkedList<>();
|
List<Recipient> recipientList = new LinkedList<>();
|
||||||
|
|
||||||
@ -88,16 +88,16 @@ public class RecipientProvider {
|
|||||||
recipientList.add(getRecipient(context, recipientId, asynchronous));
|
recipientList.add(getRecipient(context, recipientId, asynchronous));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asynchronous) cachedRecipients = new Recipients(recipientList, getRecipientsPreferencesAsync(context, recipientIds));
|
if (asynchronous) cachedRecipients = new Recipients(recipientList, cachedRecipients, getRecipientsPreferencesAsync(context, recipientIds));
|
||||||
else cachedRecipients = new Recipients(recipientList, getRecipientsPreferencesSync(context, recipientIds));
|
else cachedRecipients = new Recipients(recipientList, getRecipientsPreferencesSync(context, recipientIds));
|
||||||
|
|
||||||
recipientsCache.put(new RecipientIds(recipientIds), cachedRecipients);
|
recipientsCache.set(new RecipientIds(recipientIds), cachedRecipients);
|
||||||
return cachedRecipients;
|
return cachedRecipients;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearCache() {
|
void clearCache() {
|
||||||
recipientCache.clear();
|
recipientCache.reset();
|
||||||
recipientsCache.clear();
|
recipientsCache.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private @NonNull ListenableFutureTask<RecipientDetails> getRecipientDetailsAsync(final Context context,
|
private @NonNull ListenableFutureTask<RecipientDetails> getRecipientDetailsAsync(final Context context,
|
||||||
@ -218,6 +218,46 @@ public class RecipientProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class RecipientCache {
|
||||||
|
|
||||||
|
private final Map<Long,Recipient> cache = new LRUCache<>(1000);
|
||||||
|
|
||||||
|
public synchronized Recipient get(long recipientId) {
|
||||||
|
return cache.get(recipientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void set(long recipientId, Recipient recipient) {
|
||||||
|
cache.put(recipientId, recipient);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void reset() {
|
||||||
|
for (Recipient recipient : cache.values()) {
|
||||||
|
recipient.setStale();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RecipientsCache {
|
||||||
|
|
||||||
|
private final Map<RecipientIds,Recipients> cache = new LRUCache<>(1000);
|
||||||
|
|
||||||
|
public synchronized Recipients get(RecipientIds ids) {
|
||||||
|
return cache.get(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void set(RecipientIds ids, Recipients recipients) {
|
||||||
|
cache.put(ids, recipients);
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void reset() {
|
||||||
|
for (Recipients recipients : cache.values()) {
|
||||||
|
recipients.setStale();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -55,9 +55,10 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
|
|||||||
private long mutedUntil = 0;
|
private long mutedUntil = 0;
|
||||||
private boolean blocked = false;
|
private boolean blocked = false;
|
||||||
private VibrateState vibrate = VibrateState.DEFAULT;
|
private VibrateState vibrate = VibrateState.DEFAULT;
|
||||||
|
private boolean stale = false;
|
||||||
|
|
||||||
Recipients() {
|
Recipients() {
|
||||||
this(new LinkedList<Recipient>(), (RecipientsPreferences)null);
|
this(new LinkedList<Recipient>(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
Recipients(List<Recipient> recipients, @Nullable RecipientsPreferences preferences) {
|
Recipients(List<Recipient> recipients, @Nullable RecipientsPreferences preferences) {
|
||||||
@ -71,9 +72,19 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Recipients(List<Recipient> recipients, ListenableFutureTask<RecipientsPreferences> preferences) {
|
Recipients(@NonNull List<Recipient> recipients,
|
||||||
|
@Nullable Recipients stale,
|
||||||
|
@NonNull ListenableFutureTask<RecipientsPreferences> preferences)
|
||||||
|
{
|
||||||
this.recipients = recipients;
|
this.recipients = recipients;
|
||||||
|
|
||||||
|
if (stale != null) {
|
||||||
|
ringtone = stale.ringtone;
|
||||||
|
mutedUntil = stale.mutedUntil;
|
||||||
|
vibrate = stale.vibrate;
|
||||||
|
blocked = stale.blocked;
|
||||||
|
}
|
||||||
|
|
||||||
preferences.addListener(new FutureTaskListener<RecipientsPreferences>() {
|
preferences.addListener(new FutureTaskListener<RecipientsPreferences>() {
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(RecipientsPreferences result) {
|
public void onSuccess(RecipientsPreferences result) {
|
||||||
@ -304,6 +315,13 @@ public class Recipients implements Iterable<Recipient>, RecipientModifiedListene
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isStale() {
|
||||||
|
return stale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setStale() {
|
||||||
|
this.stale = true;
|
||||||
|
}
|
||||||
|
|
||||||
public interface RecipientsModifiedListener {
|
public interface RecipientsModifiedListener {
|
||||||
public void onModified(Recipients recipient);
|
public void onModified(Recipients recipient);
|
||||||
|
Loading…
Reference in New Issue
Block a user