From 05540fd103a99eed102f510f05d1379920544e57 Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Sun, 25 Feb 2018 00:00:13 +0100 Subject: [PATCH 1/4] Unregister fragment update listener when destorying view --- .../src/main/java/com/health/openscale/core/OpenScale.java | 4 ++++ .../com/health/openscale/gui/fragments/GraphFragment.java | 6 ++++++ .../health/openscale/gui/fragments/OverviewFragment.java | 6 ++++++ .../health/openscale/gui/fragments/StatisticsFragment.java | 6 ++++++ .../com/health/openscale/gui/fragments/TableFragment.java | 6 ++++++ 5 files changed, 28 insertions(+) diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java index 21b47b5f..c2f7b105 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java @@ -461,6 +461,10 @@ public class OpenScale { fragment.updateOnView(scaleMeasurementList); } + public void unregisterFragment(FragmentUpdateListener fragment) { + fragmentList.remove(fragment); + } + public void updateScaleData() { int selectedUserId = getSelectedScaleUserId(); diff --git a/android_app/app/src/main/java/com/health/openscale/gui/fragments/GraphFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/fragments/GraphFragment.java index e024d719..69f188d3 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/fragments/GraphFragment.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/fragments/GraphFragment.java @@ -226,6 +226,12 @@ public class GraphFragment extends Fragment implements FragmentUpdateListener { return graphView; } + @Override + public void onDestroyView() { + OpenScale.getInstance(getContext()).unregisterFragment(this); + super.onDestroyView(); + } + @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); diff --git a/android_app/app/src/main/java/com/health/openscale/gui/fragments/OverviewFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/fragments/OverviewFragment.java index 32fadec2..c4f75770 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/fragments/OverviewFragment.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/fragments/OverviewFragment.java @@ -148,6 +148,12 @@ public class OverviewFragment extends Fragment implements FragmentUpdateListener return overviewView; } + @Override + public void onDestroyView() { + OpenScale.getInstance(getContext()).unregisterFragment(this); + super.onDestroyView(); + } + @Override public void updateOnView(List scaleMeasurementList) { if (scaleMeasurementList.isEmpty()) { diff --git a/android_app/app/src/main/java/com/health/openscale/gui/fragments/StatisticsFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/fragments/StatisticsFragment.java index 81b8509d..165a42f9 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/fragments/StatisticsFragment.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/fragments/StatisticsFragment.java @@ -156,6 +156,12 @@ public class StatisticsFragment extends Fragment implements FragmentUpdateListen return statisticsView; } + @Override + public void onDestroyView() { + OpenScale.getInstance(getContext()).unregisterFragment(this); + super.onDestroyView(); + } + @Override public void updateOnView(List scaleMeasurementList) { currentScaleUser = OpenScale.getInstance(getContext()).getSelectedScaleUser(); diff --git a/android_app/app/src/main/java/com/health/openscale/gui/fragments/TableFragment.java b/android_app/app/src/main/java/com/health/openscale/gui/fragments/TableFragment.java index da5f5376..455ec1a5 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/fragments/TableFragment.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/fragments/TableFragment.java @@ -97,6 +97,12 @@ public class TableFragment extends Fragment implements FragmentUpdateListener { return tableView; } + @Override + public void onDestroyView() { + OpenScale.getInstance(getContext()).unregisterFragment(this); + super.onDestroyView(); + } + @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); From eb567e9b5a28bb04cafdd903629f503bc89e2c27 Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Sun, 25 Feb 2018 00:01:03 +0100 Subject: [PATCH 2/4] Make sure OpenScale instance only holds an application context --- .../app/src/main/java/com/health/openscale/core/OpenScale.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java index c2f7b105..e13b6d8d 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/OpenScale.java @@ -94,7 +94,7 @@ public class OpenScale { public static OpenScale getInstance(Context context) { if (instance == null) { - instance = new OpenScale(context); + instance = new OpenScale(context.getApplicationContext()); } return instance; From 5c1ef0cf5747a23279a603785173fa90968107d7 Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Sun, 25 Feb 2018 23:07:07 +0100 Subject: [PATCH 3/4] Fix fragment leak By forcing transactions to run before creating new fragment we don't end up with two fragments due to selectDrawerItem being called twice during creation. Fixes #175 --- .../health/openscale/gui/MainActivity.java | 58 ++++++++++--------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java index b8cf201e..49c7f57f 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java @@ -37,6 +37,7 @@ import android.support.design.widget.BottomNavigationView; import android.support.design.widget.NavigationView; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentTransaction; import android.support.v4.content.FileProvider; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; @@ -80,7 +81,6 @@ public class MainActivity extends AppCompatActivity private static final int IMPORT_DATA_REQUEST = 100; - private Fragment currentFragment; private DrawerLayout drawerLayout; private Toolbar toolbar; private NavigationView navDrawer; @@ -110,8 +110,6 @@ public class MainActivity extends AppCompatActivity setContentView(R.layout.activity_main); - currentFragment = null; - // Set a Toolbar to replace the ActionBar. toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); @@ -288,28 +286,23 @@ public class MainActivity extends AppCompatActivity Class fragmentClass; String fragmentTitle; - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); - - switch(menuItemId) { + switch (menuItemId) { + default: case R.id.nav_overview: fragmentClass = OverviewFragment.class; fragmentTitle = getResources().getString(R.string.title_overview); - prefs.edit().putInt("lastFragmentId", menuItemId).commit(); break; case R.id.nav_graph: fragmentClass = GraphFragment.class; fragmentTitle = getResources().getString(R.string.title_graph); - prefs.edit().putInt("lastFragmentId", menuItemId).commit(); break; case R.id.nav_table: fragmentClass = TableFragment.class; fragmentTitle = getResources().getString(R.string.title_table); - prefs.edit().putInt("lastFragmentId", menuItemId).commit(); break; case R.id.nav_statistic: fragmentClass = StatisticsFragment.class; fragmentTitle = getResources().getString(R.string.title_statistics); - prefs.edit().putInt("lastFragmentId", menuItemId).commit(); break; case R.id.nav_settings: Intent settingsIntent = new Intent(this, SettingsActivity.class); @@ -322,35 +315,45 @@ public class MainActivity extends AppCompatActivity startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/oliexdev/openScale/wiki"))); drawerLayout.closeDrawers(); return; - default: - fragmentClass = OverviewFragment.class; - fragmentTitle = getResources().getString(R.string.title_overview); - prefs.edit().putInt("lastFragmentId", menuItemId).commit(); } + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + prefs.edit().putInt("lastFragmentId", menuItemId).commit(); + FragmentManager fragmentManager = getSupportFragmentManager(); - // hide previous fragment if it available - if (currentFragment != null) { - fragmentManager.beginTransaction().hide(currentFragment).commit(); + // Make sure that any pending transaction completes so that added fragments are + // actually added and won't get added again (may happen during activity creation + // when this method is called twice). + fragmentManager.executePendingTransactions(); + + FragmentTransaction transaction = fragmentManager.beginTransaction(); + final String tag = String.valueOf(menuItemId); + + boolean found = false; + for (Fragment fragment : fragmentManager.getFragments()) { + if (fragment.getTag().equals(tag)) { + // Show selected fragment if already added + transaction.show(fragment); + found = true; + } + else if (!fragment.isHidden()) { + // Hide currently shown fragment + transaction.hide(fragment); + } } - // try to find selected fragment - currentFragment = fragmentManager.findFragmentByTag(""+menuItemId); - - // if fragment not found then add the fragment - if (currentFragment == null) { + // If fragment isn't found then add it + if (!found) { try { - currentFragment = (Fragment) fragmentClass.newInstance(); + transaction.add(R.id.fragment_content, (Fragment) fragmentClass.newInstance(), tag); } catch (Exception e) { e.printStackTrace(); } - - fragmentManager.beginTransaction().add(R.id.fragment_content, currentFragment, "" + menuItemId).commit(); - } else { // otherwise show fragment - fragmentManager.beginTransaction().show(currentFragment).commit(); } + transaction.commit(); + // Set action bar title setTitle(fragmentTitle); @@ -654,7 +657,6 @@ public class MainActivity extends AppCompatActivity R.string.permission_not_granted), Toast.LENGTH_SHORT).show(); } - currentFragment.onRequestPermissionsResult(requestCode, permissions, grantResults); super.onRequestPermissionsResult(requestCode, permissions, grantResults); } From 84c9ba03d24173416bd46639dde9bffe1d3cbcf8 Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Sun, 25 Feb 2018 23:09:13 +0100 Subject: [PATCH 4/4] MenuItem doesn't have to be static --- .../src/main/java/com/health/openscale/gui/MainActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java b/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java index 49c7f57f..ea9f00c5 100644 --- a/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java +++ b/android_app/app/src/main/java/com/health/openscale/gui/MainActivity.java @@ -77,7 +77,7 @@ public class MainActivity extends AppCompatActivity private static boolean firstAppStart = true; private static boolean valueOfCountModified = false; private static int bluetoothStatusIcon = R.drawable.ic_bluetooth_disabled; - private static MenuItem bluetoothStatus; + private MenuItem bluetoothStatus; private static final int IMPORT_DATA_REQUEST = 100;