Unregister any listeners when destroying EntryListView

We were leaking some resources by not unregistering listeners when destroying
the entry list view. The code refresh loop of the leaked view started running in
a tight infinite loop, which causes a lot of lag in the main activity.
This commit is contained in:
Alexander Bakker 2019-06-22 12:12:26 +02:00
parent f82e480c32
commit 950dcce803
5 changed files with 41 additions and 7 deletions

View file

@ -12,6 +12,11 @@ public class UiRefresher {
_handler = new Handler();
}
public void destroy() {
stop();
_listener = null;
}
public void start() {
if (_running) {
return;
@ -22,15 +27,14 @@ public class UiRefresher {
_handler.postDelayed(new Runnable() {
@Override
public void run() {
if (_running) {
_listener.onRefresh();
_handler.postDelayed(this, _listener.getMillisTillNextRefresh());
}
_listener.onRefresh();
_handler.postDelayed(this, _listener.getMillisTillNextRefresh());
}
}, _listener.getMillisTillNextRefresh());
}
public void stop() {
_handler.removeCallbacksAndMessages(null);
_running = false;
}

View file

@ -18,8 +18,6 @@ import android.widget.LinearLayout;
import android.widget.SearchView;
import android.widget.Toast;
import androidx.core.view.MenuItemCompat;
import com.beemdevelopment.aegis.AegisApplication;
import com.beemdevelopment.aegis.R;
import com.beemdevelopment.aegis.SortCategory;
@ -121,6 +119,12 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
_fabScrollHelper = new FabScrollHelper(_fabMenu);
}
@Override
protected void onDestroy() {
_entryListView.setListener(null);
super.onDestroy();
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// collapse the fab menu on touch
@ -434,6 +438,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
if (_app.isAutoLockEnabled()) {
_app.lock();
return;
}
super.onBackPressed();

View file

@ -44,6 +44,13 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
_view = view;
}
public void destroy() {
for (EntryHolder holder : _holders) {
holder.destroy();
}
_view = null;
}
public void setShowAccountName(boolean showAccountName) {
_showAccountName = showAccountName;
}
@ -118,6 +125,7 @@ public class EntryAdapter extends RecyclerView.Adapter<EntryHolder> implements I
_entries.clear();
_shownEntries.clear();
notifyDataSetChanged();
checkPeriodUniformity();
}
public void replaceEntry(DatabaseEntry newEntry) {

View file

@ -135,6 +135,10 @@ public class EntryHolder extends RecyclerView.ViewHolder {
}
}
public void destroy() {
_refresher.destroy();
}
public void startRefreshLoop() {
_refresher.start();
}

View file

@ -53,10 +53,17 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_adapter = new EntryAdapter(this);
_showProgress = false;
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
public void onDestroy() {
_adapter.destroy();
super.onDestroy();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_entry_list_view, container, false);
_progressBar = view.findViewById(R.id.progressBar);
@ -106,6 +113,12 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
_preloadSizeProvider.setView(view);
}
@Override
public void onDestroyView() {
_refresher.destroy();
super.onDestroyView();
}
public void setGroupFilter(String group, boolean apply) {
_touchCallback.setIsLongPressDragEnabled(group == null);
_adapter.setGroupFilter(group, apply);