From c6861d1e497db39368c50f46425f6718be136740 Mon Sep 17 00:00:00 2001 From: Jimmy Shih Date: Fri, 24 Aug 2012 12:46:11 -0700 Subject: [PATCH] In ChartFragment, MapFragment, StatsFragment, for callbacks from TrackDataHub, check that the fragment is resumed. In any runnable executed on the UI thread, also check that the fragment is resumed. --- .../mytracks/fragments/ChartFragment.java | 146 +++++++++------ .../apps/mytracks/fragments/MapFragment.java | 175 ++++++++++-------- .../mytracks/fragments/StatsFragment.java | 65 +++---- 3 files changed, 220 insertions(+), 166 deletions(-) diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java index b8a00acaa..2882c4713 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java +++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/ChartFragment.java @@ -83,7 +83,7 @@ public class ChartFragment extends Fragment implements TrackDataListener { private final Runnable updateChart = new Runnable() { @Override public void run() { - if (trackDataHub == null) { + if (!isResumed() || trackDataHub == null) { return; } @@ -178,111 +178,141 @@ public class ChartFragment extends Fragment implements TrackDataListener { @Override public void onTrackUpdated(Track track) { - if (track == null || track.getTripStatistics() == null) { - startTime = -1L; - return; + if (isResumed()) { + if (track == null || track.getTripStatistics() == null) { + startTime = -1L; + return; + } + startTime = track.getTripStatistics().getStartTime(); } - startTime = track.getTripStatistics().getStartTime(); } @Override public void clearTrackPoints() { - tripStatisticsBuilder = startTime != -1L ? new TripStatisticsBuilder(startTime) : null; - pendingPoints.clear(); - chartView.reset(); - - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - chartView.resetScroll(); - } - }); + if (isResumed()) { + tripStatisticsBuilder = startTime != -1L ? new TripStatisticsBuilder(startTime) : null; + pendingPoints.clear(); + chartView.reset(); + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + if (isResumed()) { + chartView.resetScroll(); + } + } + }); + } } @Override public void onSampledInTrackPoint(Location location) { - double[] data = new double[ChartView.NUM_SERIES + 1]; - fillDataPoint(location, data); - pendingPoints.add(data); + if (isResumed()) { + double[] data = new double[ChartView.NUM_SERIES + 1]; + fillDataPoint(location, data); + pendingPoints.add(data); + } } @Override public void onSampledOutTrackPoint(Location location) { - fillDataPoint(location, null); + if (isResumed()) { + fillDataPoint(location, null); + } } @Override public void onSegmentSplit(Location location) { - fillDataPoint(location, null); + if (isResumed()) { + fillDataPoint(location, null); + } } @Override public void onNewTrackPointsDone() { - chartView.addDataPoints(pendingPoints); - pendingPoints.clear(); - getActivity().runOnUiThread(updateChart); + if (isResumed()) { + chartView.addDataPoints(pendingPoints); + pendingPoints.clear(); + getActivity().runOnUiThread(updateChart); + } } @Override public void clearWaypoints() { - chartView.clearWaypoints(); + if (isResumed()) { + chartView.clearWaypoints(); + } } @Override public void onNewWaypoint(Waypoint waypoint) { - if (waypoint != null && LocationUtils.isValidLocation(waypoint.getLocation())) { + if (isResumed() && waypoint != null && LocationUtils.isValidLocation(waypoint.getLocation())) { chartView.addWaypoint(waypoint); } } @Override public void onNewWaypointsDone() { - getActivity().runOnUiThread(updateChart); + if (isResumed()) { + getActivity().runOnUiThread(updateChart); + } } @Override public boolean onMetricUnitsChanged(boolean metric) { - if (metricUnits == metric) { - return false; - } - metricUnits = metric; - chartView.setMetricUnits(metricUnits); - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - chartView.requestLayout(); + if (isResumed()) { + if (metricUnits == metric) { + return false; } - }); - return true; + metricUnits = metric; + chartView.setMetricUnits(metricUnits); + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + if (isResumed()) { + chartView.requestLayout(); + } + } + }); + return true; + } + return false; } @Override public boolean onReportSpeedChanged(boolean speed) { - if (reportSpeed == speed) { - return false; - } - reportSpeed = speed; - chartView.setReportSpeed(reportSpeed); - boolean chartShowSpeed = PreferencesUtils.getBoolean( - getActivity(), R.string.chart_show_speed_key, PreferencesUtils.CHART_SHOW_SPEED_DEFAULT); - setSeriesEnabled(ChartView.SPEED_SERIES, chartShowSpeed && reportSpeed); - setSeriesEnabled(ChartView.PACE_SERIES, chartShowSpeed && !reportSpeed); - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - chartView.requestLayout(); + if (isResumed()) { + if (reportSpeed == speed) { + return false; } - }); - return true; + reportSpeed = speed; + chartView.setReportSpeed(reportSpeed); + boolean chartShowSpeed = PreferencesUtils.getBoolean( + getActivity(), R.string.chart_show_speed_key, PreferencesUtils.CHART_SHOW_SPEED_DEFAULT); + setSeriesEnabled(ChartView.SPEED_SERIES, chartShowSpeed && reportSpeed); + setSeriesEnabled(ChartView.PACE_SERIES, chartShowSpeed && !reportSpeed); + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + if (isResumed()) { + chartView.requestLayout(); + } + } + }); + return true; + } + return false; } @Override public boolean onMinRecordingDistanceChanged(int value) { - if (minRecordingDistance == value) { - return false; + if (isResumed()) { + if (minRecordingDistance == value) { + return false; + } + minRecordingDistance = value; + return true; } - minRecordingDistance = value; - return true; + return false; } /** @@ -436,12 +466,12 @@ public class ChartFragment extends Fragment implements TrackDataListener { } else { timeOrDistance = tripStatistics.getTotalTime(); } - + elevation = tripStatisticsBuilder.getSmoothedElevation(); if (!metricUnits) { elevation *= UnitConversions.M_TO_FT; } - + speed = tripStatisticsBuilder.getSmoothedSpeed() * UnitConversions.MS_TO_KMH; if (!metricUnits) { speed *= UnitConversions.KM_TO_MI; diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/MapFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/MapFragment.java index 984a463cc..841ba20c9 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/fragments/MapFragment.java +++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/MapFragment.java @@ -275,93 +275,104 @@ public class MapFragment extends Fragment @Override public void onLocationStateChanged(LocationState state) { - final String message; - final boolean isGpsDisabled; - if (!isSelectedTrackRecording()) { - message = null; - isGpsDisabled = false; - } else { - switch (state) { - case DISABLED: - String setting = getString( - GoogleLocationUtils.isAvailable(getActivity()) ? R.string.gps_google_location_settings - : R.string.gps_location_access); - message = getString(R.string.gps_disabled, setting); - isGpsDisabled = true; - break; - case NO_FIX: - message = getString(R.string.gps_wait_for_signal); - isGpsDisabled = false; - break; - case BAD_FIX: - message = getString(R.string.gps_wait_for_better_signal); - isGpsDisabled = false; - break; - case GOOD_FIX: - message = null; - isGpsDisabled = false; - break; - default: - throw new IllegalArgumentException("Unexpected state: " + state); - } - } - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - if (message != null) { - messageTextView.setText(message); - messageTextView.setVisibility(View.VISIBLE); - - if (isGpsDisabled) { - Toast.makeText(getActivity(), R.string.gps_not_found, Toast.LENGTH_LONG).show(); - - // Click to show the location source settings - messageTextView.setOnClickListener(MapFragment.this); - } else { - messageTextView.setOnClickListener(null); - } - } else { - messageTextView.setVisibility(View.GONE); + if (isResumed()) { + final String message; + final boolean isGpsDisabled; + if (!isSelectedTrackRecording()) { + message = null; + isGpsDisabled = false; + } else { + switch (state) { + case DISABLED: + String setting = getString( + GoogleLocationUtils.isAvailable(getActivity()) ? R.string.gps_google_location_settings + : R.string.gps_location_access); + message = getString(R.string.gps_disabled, setting); + isGpsDisabled = true; + break; + case NO_FIX: + message = getString(R.string.gps_wait_for_signal); + isGpsDisabled = false; + break; + case BAD_FIX: + message = getString(R.string.gps_wait_for_better_signal); + isGpsDisabled = false; + break; + case GOOD_FIX: + message = null; + isGpsDisabled = false; + break; + default: + throw new IllegalArgumentException("Unexpected state: " + state); } } - }); + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + if (isResumed()) { + if (message == null) { + messageTextView.setVisibility(View.GONE); + return; + } + messageTextView.setText(message); + messageTextView.setVisibility(View.VISIBLE); + if (isGpsDisabled) { + Toast.makeText(getActivity(), R.string.gps_not_found, Toast.LENGTH_LONG).show(); + + // Click to show the location source settings + messageTextView.setOnClickListener(MapFragment.this); + } else { + messageTextView.setOnClickListener(null); + } + } + } + }); + } } @Override public void onLocationChanged(Location location) { - currentLocation = location; - updateCurrentLocation(); + if (isResumed()) { + currentLocation = location; + updateCurrentLocation(); + } } @Override public void onHeadingChanged(double heading) { - if (mapOverlay.setHeading((float) heading)) { - mapView.postInvalidate(); + if (isResumed()) { + if (mapOverlay.setHeading((float) heading)) { + mapView.postInvalidate(); + } } } @Override public void onSelectedTrackChanged(final Track track) { - getActivity().runOnUiThread(new Runnable() { - @Override - public void run() { - boolean hasTrack = track != null; - mapOverlay.setTrackDrawingEnabled(hasTrack); + if (isResumed()) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + if (isResumed()) { + boolean hasTrack = track != null; + mapOverlay.setTrackDrawingEnabled(hasTrack); - if (hasTrack) { - synchronized (this) { - /* - * Synchronize to prevent race condition in changing markerTrackId - * and markerId variables. - */ - currentSelectedTrackId = track.getId(); - updateMap(track); + if (hasTrack) { + synchronized (this) { + /* + * Synchronize to prevent race condition in changing + * markerTrackId and markerId variables. + */ + currentSelectedTrackId = track.getId(); + updateMap(track); + } + mapOverlay.setShowEndMarker(!isSelectedTrackRecording()); + } + mapView.invalidate(); } - mapOverlay.setShowEndMarker(!isSelectedTrackRecording()); } - mapView.invalidate(); - } - }); + }); + } } @Override @@ -371,12 +382,16 @@ public class MapFragment extends Fragment @Override public void clearTrackPoints() { - mapOverlay.clearPoints(); + if (isResumed()) { + mapOverlay.clearPoints(); + } } @Override public void onSampledInTrackPoint(Location location) { - mapOverlay.addLocation(location); + if (isResumed()) { + mapOverlay.addLocation(location); + } } @Override @@ -386,22 +401,28 @@ public class MapFragment extends Fragment @Override public void onSegmentSplit(Location location) { - mapOverlay.addSegmentSplit(); + if (isResumed()) { + mapOverlay.addSegmentSplit(); + } } @Override public void onNewTrackPointsDone() { - mapView.postInvalidate(); + if (isResumed()) { + mapView.postInvalidate(); + } } @Override public void clearWaypoints() { - mapOverlay.clearWaypoints(); + if (isResumed()) { + mapOverlay.clearWaypoints(); + } } @Override public void onNewWaypoint(Waypoint waypoint) { - if (waypoint != null && LocationUtils.isValidLocation(waypoint.getLocation())) { + if (isResumed() && waypoint != null && LocationUtils.isValidLocation(waypoint.getLocation())) { // TODO: Optimize locking inside addWaypoint mapOverlay.addWaypoint(waypoint); } @@ -409,7 +430,9 @@ public class MapFragment extends Fragment @Override public void onNewWaypointsDone() { - mapView.postInvalidate(); + if (isResumed()) { + mapView.postInvalidate(); + } } @Override diff --git a/MyTracks/src/com/google/android/apps/mytracks/fragments/StatsFragment.java b/MyTracks/src/com/google/android/apps/mytracks/fragments/StatsFragment.java index e4c9b6fb4..e7e3a292d 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/fragments/StatsFragment.java +++ b/MyTracks/src/com/google/android/apps/mytracks/fragments/StatsFragment.java @@ -58,10 +58,9 @@ public class StatsFragment extends Fragment implements TrackDataListener { // A runnable to update the total time field. private final Runnable updateTotalTime = new Runnable() { public void run() { - FragmentActivity activity = getActivity(); - if (activity != null && lastTripStatistics != null && isSelectedTrackRecording() - && !isSelectedTrackPaused()) { - StatsUtils.setTotalTimeValue(activity, System.currentTimeMillis() + if (isResumed() && isSelectedTrackRecording() && !isSelectedTrackPaused() + && lastTripStatistics != null) { + StatsUtils.setTotalTimeValue(getActivity(), System.currentTimeMillis() - lastTripStatistics.getStopTime() + lastTripStatistics.getTotalTime()); } } @@ -74,11 +73,8 @@ public class StatsFragment extends Fragment implements TrackDataListener { @Override public void run() { Log.d(TAG, "UI update thread started"); - while (isSelectedTrackRecording()) { - FragmentActivity activity = getActivity(); - if (activity != null) { - activity.runOnUiThread(updateTotalTime); - } + while (isResumed() && isSelectedTrackRecording()) { + getActivity().runOnUiThread(updateTotalTime); try { Thread.sleep(1000L); } catch (InterruptedException e) { @@ -121,12 +117,13 @@ public class StatsFragment extends Fragment implements TrackDataListener { @Override public void onLocationStateChanged(LocationState state) { if (isResumed() && state != LocationState.GOOD_FIX) { - final FragmentActivity activity = getActivity(); - activity.runOnUiThread(new Runnable() { + getActivity().runOnUiThread(new Runnable() { @Override public void run() { - lastLocation = null; - StatsUtils.setLocationValues(activity, lastLocation, true); + if (isResumed()) { + lastLocation = null; + StatsUtils.setLocationValues(getActivity(), lastLocation, true); + } } }); } @@ -135,17 +132,18 @@ public class StatsFragment extends Fragment implements TrackDataListener { @Override public void onLocationChanged(final Location location) { if (isResumed()) { - final FragmentActivity activity = getActivity(); - activity.runOnUiThread(new Runnable() { + getActivity().runOnUiThread(new Runnable() { @Override public void run() { - if (isSelectedTrackRecording() && !isSelectedTrackPaused()) { - lastLocation = location; - StatsUtils.setLocationValues(activity, location, true); - } else { - if (lastLocation != null) { - lastLocation = null; - StatsUtils.setLocationValues(activity, lastLocation, true); + if (isResumed()) { + if (isSelectedTrackRecording() && !isSelectedTrackPaused()) { + lastLocation = location; + StatsUtils.setLocationValues(getActivity(), location, true); + } else { + if (lastLocation != null) { + lastLocation = null; + StatsUtils.setLocationValues(getActivity(), lastLocation, true); + } } } } @@ -175,12 +173,13 @@ public class StatsFragment extends Fragment implements TrackDataListener { @Override public void onTrackUpdated(final Track track) { if (isResumed()) { - final FragmentActivity activity = getActivity(); - activity.runOnUiThread(new Runnable() { + getActivity().runOnUiThread(new Runnable() { @Override public void run() { - lastTripStatistics = track != null ? track.getTripStatistics() : null; - updateUi(activity); + if (isResumed()) { + lastTripStatistics = track != null ? track.getTripStatistics() : null; + updateUi(getActivity()); + } } }); } @@ -229,11 +228,12 @@ public class StatsFragment extends Fragment implements TrackDataListener { @Override public boolean onMetricUnitsChanged(final boolean metric) { if (isResumed()) { - final FragmentActivity activity = getActivity(); - activity.runOnUiThread(new Runnable() { + getActivity().runOnUiThread(new Runnable() { @Override public void run() { - updateUi(activity); + if (isResumed()) { + updateUi(getActivity()); + } } }); } @@ -243,11 +243,12 @@ public class StatsFragment extends Fragment implements TrackDataListener { @Override public boolean onReportSpeedChanged(final boolean speed) { if (isResumed()) { - final FragmentActivity activity = getActivity(); - activity.runOnUiThread(new Runnable() { + getActivity().runOnUiThread(new Runnable() { @Override public void run() { - updateUi(activity); + if (isResumed()) { + updateUi(getActivity()); + } } }); }