From 59316ae3c407abd04a45538d17b9631c776bdf25 Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Wed, 28 Dec 2016 14:44:16 +0000 Subject: [PATCH] Fix memory leaks caused by periodic view refreshing tasks. --- .../briar/android/blog/BasePostFragment.java | 19 ++++++++++--------- .../briar/android/blog/FeedFragment.java | 2 +- .../briar/android/util/UiUtils.java | 9 +++++---- .../briar/android/view/BriarRecyclerView.java | 16 ++++++++++------ 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/BasePostFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/BasePostFragment.java index 5787e115ed..7408d9d7fb 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/blog/BasePostFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/BasePostFragment.java @@ -1,6 +1,8 @@ package org.briarproject.briar.android.blog; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.support.annotation.CallSuper; import android.support.annotation.UiThread; import android.view.LayoutInflater; @@ -20,7 +22,7 @@ import javax.annotation.Nullable; import static android.view.View.INVISIBLE; import static android.view.View.VISIBLE; -import static org.briarproject.briar.android.util.UiUtils.MIN_RESOLUTION; +import static org.briarproject.briar.android.util.UiUtils.MIN_DATE_RESOLUTION; @UiThread @MethodsNotNullByDefault @@ -32,8 +34,9 @@ abstract class BasePostFragment extends BaseFragment { private static final Logger LOG = Logger.getLogger(BasePostFragment.class.getName()); + private final Handler handler = new Handler(Looper.getMainLooper()); + protected MessageId postId; - private View view; private ProgressBar progressBar; private BlogPostViewHolder ui; private BlogPostItem post; @@ -50,7 +53,7 @@ abstract class BasePostFragment extends BaseFragment { if (p == null) throw new IllegalStateException("No post ID in args"); postId = new MessageId(p); - view = inflater.inflate(R.layout.fragment_blog_post, container, + View view = inflater.inflate(R.layout.fragment_blog_post, container, false); progressBar = (ProgressBar) view.findViewById(R.id.progressBar); progressBar.setVisibility(VISIBLE); @@ -83,21 +86,19 @@ abstract class BasePostFragment extends BaseFragment { refresher = new Runnable() { @Override public void run() { - if (ui == null) return; LOG.info("Updating Content..."); - ui.updateDate(post.getTimestamp()); - view.postDelayed(refresher, MIN_RESOLUTION); + handler.postDelayed(refresher, MIN_DATE_RESOLUTION); } }; LOG.info("Adding Handler Callback"); - view.postDelayed(refresher, MIN_RESOLUTION); + handler.postDelayed(refresher, MIN_DATE_RESOLUTION); } private void stopPeriodicUpdate() { - if (refresher != null && ui != null) { + if (refresher != null) { LOG.info("Removing Handler Callback"); - view.removeCallbacks(refresher); + handler.removeCallbacks(refresher); } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedFragment.java index 7c5a2c8980..82a4320918 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/blog/FeedFragment.java @@ -105,6 +105,7 @@ public class FeedFragment extends BaseFragment implements public void onStart() { super.onStart(); feedController.onStart(); + list.startPeriodicUpdate(); loadPersonalBlog(); loadBlogPosts(false); } @@ -157,7 +158,6 @@ public class FeedFragment extends BaseFragment implements handleDbException(exception); } }); - list.startPeriodicUpdate(); } @Override diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java index 24c25b4919..57788d4f1a 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java @@ -33,7 +33,7 @@ import static android.text.format.DateUtils.WEEK_IN_MILLIS; public class UiUtils { - public static final long MIN_RESOLUTION = MINUTE_IN_MILLIS; + public static final long MIN_DATE_RESOLUTION = MINUTE_IN_MILLIS; public static final int TEASER_LENGTH = 320; public static final float GREY_OUT = 0.5f; @@ -51,15 +51,16 @@ public class UiUtils { FORMAT_SHOW_DATE | FORMAT_ABBREV_TIME | FORMAT_ABBREV_MONTH; long diff = System.currentTimeMillis() - time; - if (diff < MIN_RESOLUTION) return ctx.getString(R.string.now); + if (diff < MIN_DATE_RESOLUTION) return ctx.getString(R.string.now); if (diff >= DAY_IN_MILLIS && diff < WEEK_IN_MILLIS) { // also show time when older than a day, but newer than a week return DateUtils.getRelativeDateTimeString(ctx, time, - MIN_RESOLUTION, WEEK_IN_MILLIS, flags).toString(); + MIN_DATE_RESOLUTION, WEEK_IN_MILLIS, flags).toString(); } // otherwise just show "...ago" or date string return DateUtils.getRelativeTimeSpanString(time, - System.currentTimeMillis(), MIN_RESOLUTION, flags).toString(); + System.currentTimeMillis(), + MIN_DATE_RESOLUTION, flags).toString(); } public static SpannableStringBuilder getTeaser(Context ctx, Spanned body) { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/BriarRecyclerView.java b/briar-android/src/main/java/org/briarproject/briar/android/view/BriarRecyclerView.java index 1f32f5a75f..e4235c2dda 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/view/BriarRecyclerView.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/view/BriarRecyclerView.java @@ -2,6 +2,8 @@ package org.briarproject.briar.android.view; import android.content.Context; import android.content.res.TypedArray; +import android.os.Handler; +import android.os.Looper; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.Adapter; import android.util.AttributeSet; @@ -17,14 +19,15 @@ import java.util.logging.Logger; import javax.annotation.Nullable; -import static org.briarproject.briar.android.util.UiUtils.MIN_RESOLUTION; +import static org.briarproject.briar.android.util.UiUtils.MIN_DATE_RESOLUTION; public class BriarRecyclerView extends FrameLayout { - private static final long DEFAULT_REFRESH_INTERVAL = MIN_RESOLUTION; private static final Logger LOG = Logger.getLogger(BriarRecyclerView.class.getName()); + private final Handler handler = new Handler(Looper.getMainLooper()); + private RecyclerView recyclerView; private TextView emptyView; private ProgressBar progressBar; @@ -192,18 +195,19 @@ public class BriarRecyclerView extends FrameLayout { @Override public void run() { LOG.info("Updating Content..."); - recyclerView.getAdapter().notifyDataSetChanged(); - postDelayed(refresher, DEFAULT_REFRESH_INTERVAL); + Adapter adapter = recyclerView.getAdapter(); + adapter.notifyItemRangeChanged(0, adapter.getItemCount()); + handler.postDelayed(refresher, MIN_DATE_RESOLUTION); } }; LOG.info("Adding Handler Callback"); - postDelayed(refresher, DEFAULT_REFRESH_INTERVAL); + handler.postDelayed(refresher, MIN_DATE_RESOLUTION); } public void stopPeriodicUpdate() { if (refresher != null) { LOG.info("Removing Handler Callback"); - removeCallbacks(refresher); + handler.removeCallbacks(refresher); } } -- GitLab