mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Merge branch '851-refresher-memory-leak' into 'master'
Fix memory leaks caused by periodic view refreshing tasks This branch implements @goapunk's suggested solution to #851. Credit goes to @ernir for finding the bug and the initial solution, and @goapunk for the improved solution - I just did a quick implementation so we can get this fixed as quickly as possible. Closes #851 See merge request !473
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user