Fixed multiple observers

pull/146/head
M66B 7 years ago
parent 3aa89cae97
commit c4733427ae

@ -96,6 +96,7 @@ import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction; import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.paging.AsyncPagedListDiffer; import androidx.paging.AsyncPagedListDiffer;
@ -188,6 +189,9 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
private Group grpAttachments; private Group grpAttachments;
private Group grpExpanded; private Group grpExpanded;
private LiveData<List<EntityAttachment>> liveAttachments = null;
private Observer<List<EntityAttachment>> observerAttachments = null;
ViewHolder(View itemView) { ViewHolder(View itemView) {
super(itemView); super(itemView);
@ -400,25 +404,16 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
} }
if (debug) { if (debug) {
db.operation().getOperationsByMessage(message.id).removeObservers(owner); String text = message.error +
db.operation().getOperationsByMessage(message.id).observe(owner, new Observer<List<EntityOperation>>() { "\n" + message.uid + "/" + message.id + " " + df.format(new Date(message.received)) +
@Override "\n" + (message.ui_hide ? "HIDDEN " : "") +
public void onChanged(List<EntityOperation> operations) { "seen=" + message.seen + "/" + message.ui_seen + "/" + message.unseen +
String text = message.error + " found=" + message.ui_found +
"\n" + message.uid + "/" + message.id + " " + df.format(new Date(message.received)) + "\n" + message.msgid +
"\n" + (message.ui_hide ? "HIDDEN " : "") + "\n" + message.thread;
"seen=" + message.seen + "/" + message.ui_seen + "/" + message.unseen +
" found=" + message.ui_found + tvError.setText(text);
"\n" + message.msgid + tvError.setVisibility(View.VISIBLE);
"\n" + message.thread;
if (operations != null)
for (EntityOperation op : operations)
text += "\n" + op.id + ":" + op.name + " " + df.format(new Date(op.created));
tvError.setText(text);
tvError.setVisibility(View.VISIBLE);
}
});
} else { } else {
tvError.setText(message.error); tvError.setText(message.error);
tvError.setVisibility(message.error == null ? View.GONE : View.VISIBLE); tvError.setVisibility(message.error == null ? View.GONE : View.VISIBLE);
@ -451,9 +446,6 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
grpAttachments.setVisibility(message.attachments > 0 && show_expanded ? View.VISIBLE : View.GONE); grpAttachments.setVisibility(message.attachments > 0 && show_expanded ? View.VISIBLE : View.GONE);
grpExpanded.setVisibility(viewType == ViewType.THREAD && show_expanded ? View.VISIBLE : View.GONE); grpExpanded.setVisibility(viewType == ViewType.THREAD && show_expanded ? View.VISIBLE : View.GONE);
db.folder().liveSystemFolders(message.account).removeObservers(owner);
db.attachment().liveAttachments(message.id).removeObservers(owner);
bnvActions.setTag(null); bnvActions.setTag(null);
if (show_expanded) { if (show_expanded) {
@ -488,9 +480,18 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
bodyTask.load(context, owner, args); bodyTask.load(context, owner, args);
} }
db.folder().liveSystemFolders(message.account).observe(owner, new Observer<List<EntityFolder>>() { Bundle sargs = new Bundle();
sargs.putLong("account", message.account);
new SimpleTask<List<EntityFolder>>() {
@Override @Override
public void onChanged(@Nullable List<EntityFolder> folders) { protected List<EntityFolder> onLoad(Context context, Bundle args) {
long account = args.getLong("account");
return DB.getInstance(context).folder().getSystemFolders(account);
}
@Override
protected void onLoaded(Bundle args, List<EntityFolder> folders) {
boolean hasJunk = false; boolean hasJunk = false;
boolean hasTrash = false; boolean hasTrash = false;
boolean hasArchive = false; boolean hasArchive = false;
@ -524,30 +525,43 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
bnvActions.setVisibility(View.VISIBLE); bnvActions.setVisibility(View.VISIBLE);
vSeparatorBody.setVisibility(View.GONE); vSeparatorBody.setVisibility(View.GONE);
} }
});
@Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(context, owner, ex);
}
}.load(context, owner, sargs);
// Observe attachments // Observe attachments
db.attachment().liveAttachments(message.id).observe(owner, observerAttachments = new Observer<List<EntityAttachment>>() {
new Observer<List<EntityAttachment>>() { @Override
@Override public void onChanged(@Nullable List<EntityAttachment> attachments) {
public void onChanged(@Nullable List<EntityAttachment> attachments) { if (attachments == null)
if (attachments == null) attachments = new ArrayList<>();
attachments = new ArrayList<>();
adapter.set(attachments); adapter.set(attachments);
if (message.content) { if (message.content) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putSerializable("message", message); args.putSerializable("message", message);
bodyTask.load(context, owner, args); bodyTask.load(context, owner, args);
} }
} }
}); };
liveAttachments = db.attachment().liveAttachments(message.id);
liveAttachments.observe(owner, observerAttachments);
} }
itemView.setActivated(selectionTracker != null && selectionTracker.isSelected(message.id)); itemView.setActivated(selectionTracker != null && selectionTracker.isSelected(message.id));
} }
void unbind() {
if (liveAttachments != null) {
liveAttachments.removeObserver(observerAttachments);
liveAttachments = null;
}
}
@Override @Override
public void onClick(View view) { public void onClick(View view) {
int pos = getAdapterPosition(); int pos = getAdapterPosition();
@ -1040,10 +1054,14 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
} }
private void onAnswer(final ActionData data) { private void onAnswer(final ActionData data) {
final DB db = DB.getInstance(context); new SimpleTask<List<EntityAnswer>>() {
db.answer().liveAnswers().observe(owner, new Observer<List<EntityAnswer>>() { @Override
protected List<EntityAnswer> onLoad(Context context, Bundle args) {
return DB.getInstance(context).answer().getAnswers();
}
@Override @Override
public void onChanged(List<EntityAnswer> answers) { protected void onLoaded(Bundle args, List<EntityAnswer> answers) {
if (answers == null || answers.size() == 0) { if (answers == null || answers.size() == 0) {
Snackbar snackbar = Snackbar.make( Snackbar snackbar = Snackbar.make(
itemView, itemView,
@ -1094,10 +1112,13 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
popupMenu.show(); popupMenu.show();
} }
}
db.answer().liveAnswers().removeObservers(owner); @Override
protected void onException(Bundle args, Throwable ex) {
Helper.unexpectedError(context, owner, ex);
} }
}); }.load(context, owner, new Bundle());
} }
private void onUnseen(final ActionData data) { private void onUnseen(final ActionData data) {
@ -1616,6 +1637,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
@Override @Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) { public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.unbind();
holder.unwire(); holder.unwire();
TupleMessageEx message = differ.getItem(position); TupleMessageEx message = differ.getItem(position);
@ -1627,6 +1649,11 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
} }
} }
@Override
public void onViewRecycled(@NonNull ViewHolder holder) {
holder.unbind();
}
void setSelectionTracker(SelectionTracker<Long> selectionTracker) { void setSelectionTracker(SelectionTracker<Long> selectionTracker) {
this.selectionTracker = selectionTracker; this.selectionTracker = selectionTracker;
} }

@ -97,6 +97,11 @@ public interface DaoFolder {
@Query("SELECT * FROM folder ORDER BY account, name") @Query("SELECT * FROM folder ORDER BY account, name")
List<EntityFolder> getFolders(); List<EntityFolder> getFolders();
@Query("SELECT * FROM folder" +
" WHERE folder.account = :account" +
" AND type <> '" + EntityFolder.USER + "'")
List<EntityFolder> getSystemFolders(long account);
@Query("SELECT * FROM folder WHERE id = :id") @Query("SELECT * FROM folder WHERE id = :id")
EntityFolder getFolder(Long id); EntityFolder getFolder(Long id);

@ -105,6 +105,7 @@ import androidx.core.content.ContextCompat;
import androidx.cursoradapter.widget.SimpleCursorAdapter; import androidx.cursoradapter.widget.SimpleCursorAdapter;
import androidx.fragment.app.FragmentTransaction; import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -1347,8 +1348,9 @@ public class FragmentCompose extends FragmentEx {
final DB db = DB.getInstance(getContext()); final DB db = DB.getInstance(getContext());
db.account().liveAccounts(true).removeObservers(getViewLifecycleOwner());
db.account().liveAccounts(true).observe(getViewLifecycleOwner(), new Observer<List<EntityAccount>>() { db.account().liveAccounts(true).observe(getViewLifecycleOwner(), new Observer<List<EntityAccount>>() {
private LiveData<List<EntityIdentity>> liveIdentities = null;
@Override @Override
public void onChanged(List<EntityAccount> accounts) { public void onChanged(List<EntityAccount> accounts) {
if (accounts == null) if (accounts == null)
@ -1374,8 +1376,12 @@ public class FragmentCompose extends FragmentEx {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
EntityAccount account = (EntityAccount) parent.getAdapter().getItem(position); EntityAccount account = (EntityAccount) parent.getAdapter().getItem(position);
db.identity().liveIdentities(account.id, true).removeObservers(getViewLifecycleOwner()); if (liveIdentities == null)
db.identity().liveIdentities(account.id, true).observe(getViewLifecycleOwner(), new Observer<List<EntityIdentity>>() { liveIdentities = db.identity().liveIdentities(account.id, true);
else
liveIdentities.removeObservers(getViewLifecycleOwner());
liveIdentities.observe(getViewLifecycleOwner(), new Observer<List<EntityIdentity>>() {
@Override @Override
public void onChanged(@Nullable List<EntityIdentity> identities) { public void onChanged(@Nullable List<EntityIdentity> identities) {
if (identities == null) if (identities == null)
@ -1449,7 +1455,6 @@ public class FragmentCompose extends FragmentEx {
} }
}); });
db.attachment().liveAttachments(result.draft.id).removeObservers(getViewLifecycleOwner());
db.attachment().liveAttachments(result.draft.id).observe(getViewLifecycleOwner(), db.attachment().liveAttachments(result.draft.id).observe(getViewLifecycleOwner(),
new Observer<List<EntityAttachment>>() { new Observer<List<EntityAttachment>>() {
@Override @Override
@ -1462,7 +1467,6 @@ public class FragmentCompose extends FragmentEx {
} }
}); });
db.message().liveMessage(result.draft.id).removeObservers(getViewLifecycleOwner());
db.message().liveMessage(result.draft.id).observe(getViewLifecycleOwner(), new Observer<EntityMessage>() { db.message().liveMessage(result.draft.id).observe(getViewLifecycleOwner(), new Observer<EntityMessage>() {
@Override @Override
public void onChanged(final EntityMessage draft) { public void onChanged(final EntityMessage draft) {

@ -202,6 +202,7 @@ public class FragmentMessages extends FragmentEx {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putLong("account", account); args.putLong("account", account);
args.putLong("folder", folder); args.putLong("folder", folder);
new SimpleTask<Void>() { new SimpleTask<Void>() {
@Override @Override
protected Void onLoad(Context context, Bundle args) { protected Void onLoad(Context context, Bundle args) {

@ -124,6 +124,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleService; import androidx.lifecycle.LifecycleService;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND; import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
@ -1075,94 +1076,111 @@ public class ServiceSynchronize extends LifecycleService {
// Observe operations // Observe operations
Handler handler = new Handler(getMainLooper()) { Handler handler = new Handler(getMainLooper()) {
private List<Long> handling = new ArrayList<>(); private LiveData<List<EntityOperation>> liveOperations;
private final PowerManager.WakeLock wlFolder = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":folder." + folder.id);
private final ExecutorService executor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory);
@Override @Override
public void handleMessage(android.os.Message msg) { public void handleMessage(android.os.Message msg) {
Log.i(Helper.TAG, folder.name + " observe=" + msg.what); Log.i(Helper.TAG, account.name + "/" + folder.name + " observe=" + msg.what);
if (msg.what == 0) try {
db.operation().liveOperations(folder.id).removeObservers(ServiceSynchronize.this); if (msg.what == 0)
else liveOperations.removeObserver(observer);
db.operation().liveOperations(folder.id).observe(ServiceSynchronize.this, new Observer<List<EntityOperation>>() { else {
@Override liveOperations = db.operation().liveOperations(folder.id);
public void onChanged(List<EntityOperation> operations) { liveOperations.observe(ServiceSynchronize.this, observer);
boolean process = false; }
List<Long> current = new ArrayList<>(); } catch (Throwable ex) {
for (EntityOperation op : operations) { Log.e(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
if (!handling.contains(op.id)) }
process = true; }
current.add(op.id);
} private Observer<List<EntityOperation>> observer = new Observer<List<EntityOperation>>() {
handling = current; private List<Long> handling = new ArrayList<>();
private final ExecutorService executor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory);
if (handling.size() > 0 && process) { private final PowerManager.WakeLock wlFolder = pm.newWakeLock(
Log.i(Helper.TAG, folder.name + " operations=" + operations.size()); PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":folder." + folder.id);
executor.submit(new Runnable() {
@Override @Override
public void run() { public void onChanged(List<EntityOperation> operations) {
try { boolean process = false;
wlFolder.acquire(); List<Long> current = new ArrayList<>();
Log.i(Helper.TAG, folder.name + " process"); for (EntityOperation op : operations) {
if (!handling.contains(op.id))
// Get folder process = true;
IMAPFolder ifolder = null; current.add(op.id);
for (EntityFolder f : folders.keySet()) }
if (f.id.equals(folder.id)) { handling = current;
ifolder = folders.get(f); // null when polling
break;
}
final boolean shouldClose = (ifolder == null); if (handling.size() > 0 && process) {
Log.i(Helper.TAG, folder.name + " operations=" + operations.size());
executor.submit(new Runnable() {
@Override
public void run() {
try {
wlFolder.acquire();
Log.i(Helper.TAG, folder.name + " process");
// Get folder
IMAPFolder ifolder = null;
for (EntityFolder f : folders.keySet())
if (f.id.equals(folder.id)) {
ifolder = folders.get(f); // null when polling
break;
}
try { final boolean shouldClose = (ifolder == null);
Log.i(Helper.TAG, folder.name + " run " + (shouldClose ? "offline" : "online"));
if (ifolder == null) { try {
// Prevent unnecessary folder connections Log.i(Helper.TAG, folder.name + " run " + (shouldClose ? "offline" : "online"));
if (db.operation().getOperationCount(folder.id, null) == 0)
return;
db.folder().setFolderState(folder.id, "connecting"); if (ifolder == null) {
// Prevent unnecessary folder connections
if (db.operation().getOperationCount(folder.id, null) == 0)
return;
ifolder = (IMAPFolder) istore.getFolder(folder.name); db.folder().setFolderState(folder.id, "connecting");
ifolder.open(Folder.READ_WRITE);
db.folder().setFolderState(folder.id, "connected"); ifolder = (IMAPFolder) istore.getFolder(folder.name);
db.folder().setFolderError(folder.id, null); ifolder.open(Folder.READ_WRITE);
}
processOperations(account, folder, isession, istore, ifolder, state); db.folder().setFolderState(folder.id, "connected");
db.folder().setFolderError(folder.id, null);
} catch (Throwable ex) { }
Log.e(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex));
reportError(account, folder, ex); processOperations(account, folder, isession, istore, ifolder, state);
db.folder().setFolderError(folder.id, Helper.formatThrowable(ex));
state.error(); } catch (Throwable ex) {
} finally { Log.e(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex));
if (shouldClose) { reportError(account, folder, ex);
if (ifolder != null && ifolder.isOpen()) { db.folder().setFolderError(folder.id, Helper.formatThrowable(ex));
db.folder().setFolderState(folder.id, "closing"); state.error();
try { } finally {
ifolder.close(false); if (shouldClose) {
} catch (MessagingException ex) { if (ifolder != null && ifolder.isOpen()) {
Log.w(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex)); db.folder().setFolderState(folder.id, "closing");
} try {
} ifolder.close(false);
db.folder().setFolderState(folder.id, null); } catch (MessagingException ex) {
Log.w(Helper.TAG, folder.name + " " + ex + "\n" + Log.getStackTraceString(ex));
} }
} }
} finally { db.folder().setFolderState(folder.id, null);
wlFolder.release();
} }
} }
}); } finally {
wlFolder.release();
}
} }
} });
}); }
} }
@Override
public boolean equals(@Nullable Object obj) {
boolean eq = super.equals(obj);
Log.i(Helper.TAG, account.name + "/" + folder.name + " equal=" + eq + " observer=" + observer + " other=" + obj);
return eq;
}
};
}; };
// Start watching for operations // Start watching for operations
@ -2423,60 +2441,63 @@ public class ServiceSynchronize extends LifecycleService {
db.folder().setFolderError(outbox.id, null); db.folder().setFolderError(outbox.id, null);
handler = new Handler(Looper.getMainLooper()) { handler = new Handler(Looper.getMainLooper()) {
private LiveData<List<EntityOperation>> liveOperations;
@Override @Override
public void handleMessage(android.os.Message msg) { public void handleMessage(android.os.Message msg) {
Log.i(Helper.TAG, outbox.name + " observe=" + msg.what); Log.i(Helper.TAG, outbox.name + " observe=" + msg.what);
if (msg.what == 0) if (msg.what == 0)
db.operation().liveOperations(outbox.id).removeObservers(ServiceSynchronize.this); liveOperations.removeObserver(observer);
else { else {
db.operation().liveOperations(outbox.id).observe(ServiceSynchronize.this, new Observer<List<EntityOperation>>() { liveOperations = db.operation().liveOperations(outbox.id);
private List<Long> handling = new ArrayList<>(); liveOperations.observe(ServiceSynchronize.this, observer);
private ExecutorService executor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory); }
}
@Override private Observer<List<EntityOperation>> observer = new Observer<List<EntityOperation>>() {
public void onChanged(List<EntityOperation> operations) { private List<Long> handling = new ArrayList<>();
boolean process = false; private ExecutorService executor = Executors.newSingleThreadExecutor(Helper.backgroundThreadFactory);
List<Long> current = new ArrayList<>(); PowerManager pm = getSystemService(PowerManager.class);
for (EntityOperation op : operations) { PowerManager.WakeLock wl = pm.newWakeLock(
if (!handling.contains(op.id)) PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":outbox");
process = true;
current.add(op.id); @Override
} public void onChanged(List<EntityOperation> operations) {
handling = current; boolean process = false;
List<Long> current = new ArrayList<>();
if (handling.size() > 0 && process) { for (EntityOperation op : operations) {
Log.i(Helper.TAG, outbox.name + " operations=" + operations.size()); if (!handling.contains(op.id))
executor.submit(new Runnable() { process = true;
PowerManager pm = getSystemService(PowerManager.class); current.add(op.id);
PowerManager.WakeLock wl = pm.newWakeLock( }
PowerManager.PARTIAL_WAKE_LOCK, BuildConfig.APPLICATION_ID + ":outbox"); handling = current;
@Override if (handling.size() > 0 && process) {
public void run() { Log.i(Helper.TAG, outbox.name + " operations=" + operations.size());
try { executor.submit(new Runnable() {
wl.acquire(); @Override
Log.i(Helper.TAG, outbox.name + " process"); public void run() {
try {
db.folder().setFolderSyncState(outbox.id, "syncing"); wl.acquire();
processOperations(null, outbox, null, null, null, state); Log.i(Helper.TAG, outbox.name + " process");
db.folder().setFolderError(outbox.id, null);
} catch (Throwable ex) { db.folder().setFolderSyncState(outbox.id, "syncing");
Log.e(Helper.TAG, outbox.name + " " + ex + "\n" + Log.getStackTraceString(ex)); processOperations(null, outbox, null, null, null, state);
reportError(null, outbox, ex); db.folder().setFolderError(outbox.id, null);
db.folder().setFolderError(outbox.id, Helper.formatThrowable(ex)); } catch (Throwable ex) {
} finally { Log.e(Helper.TAG, outbox.name + " " + ex + "\n" + Log.getStackTraceString(ex));
db.folder().setFolderSyncState(outbox.id, null); reportError(null, outbox, ex);
wl.release(); db.folder().setFolderError(outbox.id, Helper.formatThrowable(ex));
EntityLog.log(ServiceSynchronize.this, "Outbox wake lock=" + wl.isHeld()); } finally {
} db.folder().setFolderSyncState(outbox.id, null);
} wl.release();
}); EntityLog.log(ServiceSynchronize.this, "Outbox wake lock=" + wl.isHeld());
}
} }
} });
}); }
} }
} };
}; };
handler.sendEmptyMessage(1); handler.sendEmptyMessage(1);
db.folder().setFolderState(outbox.id, "connected"); db.folder().setFolderState(outbox.id, "connected");

@ -31,11 +31,13 @@ import android.util.Log;
import java.util.List; import java.util.List;
import androidx.lifecycle.LifecycleService; import androidx.lifecycle.LifecycleService;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
@TargetApi(Build.VERSION_CODES.N) @TargetApi(Build.VERSION_CODES.N)
public class ServiceTileUnseen extends TileService { public class ServiceTileUnseen extends TileService {
LifecycleService owner = new LifecycleService(); private LifecycleService owner = new LifecycleService();
private LiveData<List<TupleMessageEx>> liveMessages;
@Override @Override
public void onCreate() { public void onCreate() {
@ -63,9 +65,8 @@ public class ServiceTileUnseen extends TileService {
public void onStartListening() { public void onStartListening() {
Log.i(Helper.TAG, "Start tile unseen"); Log.i(Helper.TAG, "Start tile unseen");
liveMessages = DB.getInstance(this).message().liveUnseenUnified();
DB db = DB.getInstance(this); liveMessages.observe(owner, new Observer<List<TupleMessageEx>>() {
db.message().liveUnseenUnified().observe(owner, new Observer<List<TupleMessageEx>>() {
@Override @Override
public void onChanged(List<TupleMessageEx> messages) { public void onChanged(List<TupleMessageEx> messages) {
Log.i(Helper.TAG, "Update tile unseen=" + messages.size()); Log.i(Helper.TAG, "Update tile unseen=" + messages.size());
@ -85,9 +86,8 @@ public class ServiceTileUnseen extends TileService {
public void onStopListening() { public void onStopListening() {
Log.i(Helper.TAG, "Stop tile unseen"); Log.i(Helper.TAG, "Stop tile unseen");
if (liveMessages != null)
DB db = DB.getInstance(this); liveMessages.removeObservers(owner);
db.message().liveUnseenUnified().removeObservers(owner);
} }
public void onClick() { public void onClick() {

Loading…
Cancel
Save