forked from upstream-mirrors/OpenTracks
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.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user