Merging from head.

This commit is contained in:
Rodrigo Damazio
2010-11-23 22:13:01 -08:00
parent 7b1302c011
commit 7abce12499
2 changed files with 93 additions and 62 deletions
+2 -2
View File
@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.maps.mytracks"
android:installLocation="auto"
android:versionCode="20"
android:versionName="1.0.19">
android:versionCode="21"
android:versionName="1.0.20">
<application android:icon="@drawable/arrow_icon"
android:label="@string/app_name"
android:backupAgent="com.google.android.apps.mytracks.io.backup.MyTracksBackupAgent">
@@ -724,7 +724,6 @@ public class TrackRecordingService extends Service implements LocationListener {
showNotification();
prefManager.shutdown();
prefManager = null;
binder = null;
checkLocationListener.cancel();
checkLocationListener = null;
timer.cancel();
@@ -735,6 +734,15 @@ public class TrackRecordingService extends Service implements LocationListener {
signalManager = null;
splitManager.shutdown();
splitManager = null;
// Make sure we have no indirect references to this service.
locationManager = null;
notificationManager = null;
providerUtils = null;
binder.detachFromService();
binder = null;
// This should be the last operation.
releaseWakeLock();
super.onDestroy();
@@ -910,75 +918,98 @@ public class TrackRecordingService extends Service implements LocationListener {
updateCurrentWaypoint();
return Long.parseLong(uri.getLastPathSegment());
}
private ServiceBinder binder = new ServiceBinder(this);
/**
* The ITrackRecordingService is defined through IDL.
* TODO: There is a bug in Android that leaks Binder instances. This bug is
* especially visible if we have a non-static class, as there is no way to
* nullify reference to the outer class (the service).
* A workaround is to use a static class and explicitly clear service
* and detach it from the underlying Binder. With this approach, we minimize
* the leak to 24 bytes per each service instance.
*
* For more details, see the following bug:
* http://code.google.com/p/android/issues/detail?id=6426.
*/
private ITrackRecordingService.Stub binder =
new ITrackRecordingService.Stub() {
@Override
public boolean isRecording() {
return TrackRecordingService.this.isRecording();
}
private static class ServiceBinder extends ITrackRecordingService.Stub {
private TrackRecordingService service;
public ServiceBinder(TrackRecordingService service) {
this.service = service;
}
/**
* Clears the reference to the outer class to minimize the leak.
*/
public void detachFromService() {
this.service = null;
attachInterface(null, null);
}
@Override
public boolean isRecording() {
return service.isRecording();
}
@Override
public long getRecordingTrackId() {
return recordingTrackId;
}
@Override
public long getRecordingTrackId() {
return service.recordingTrackId;
}
@Override
public boolean hasRecorded() {
return providerUtils.getLastTrackId() >= 0;
}
@Override
public boolean hasRecorded() {
return service.providerUtils.getLastTrackId() >= 0;
}
@Override
public long startNewTrack() {
return TrackRecordingService.this.startNewTrack();
}
@Override
public long startNewTrack() {
return service.startNewTrack();
}
/**
* Insert the given waypoint marker. Users can insert waypoint markers
* to tag locations with a name, description, category etc.
*
* @param waypoint a waypoint
* @return the unique id of the inserted marker
*/
@Override
public long insertWaypointMarker(Waypoint waypoint) {
return TrackRecordingService.this.insertWaypointMarker(waypoint);
}
/**
* Insert the given waypoint marker. Users can insert waypoint markers
* to tag locations with a name, description, category etc.
*
* @param waypoint a waypoint
* @return the unique id of the inserted marker
*/
@Override
public long insertWaypointMarker(Waypoint waypoint) {
return service.insertWaypointMarker(waypoint);
}
/**
* Insert a statistics marker. A statistics marker holds the stats for
* the last segment up to this marker.
*
* @param location the location where to insert
* @return the unique id of the inserted marker
*/
@Override
public long insertStatisticsMarker(Location location) {
return TrackRecordingService.this.insertStatisticsMarker(location);
}
/**
* Insert a statistics marker. A statistics marker holds the stats for
* the last segment up to this marker.
*
* @param location the location where to insert
* @return the unique id of the inserted marker
*/
@Override
public long insertStatisticsMarker(Location location) {
return service.insertStatisticsMarker(location);
}
@Override
public void endCurrentTrack() {
TrackRecordingService.this.endCurrentTrack();
}
@Override
public void endCurrentTrack() {
service.endCurrentTrack();
}
@Override
public void deleteAllTracks() {
if (isRecording()) {
throw new IllegalStateException(
"Cannot delete all tracks while recording!");
}
providerUtils.deleteAllTracks();
}
@Override
public void deleteAllTracks() {
if (isRecording()) {
throw new IllegalStateException(
"Cannot delete all tracks while recording!");
}
service.providerUtils.deleteAllTracks();
}
@Override
public void recordLocation(Location loc) {
onLocationChanged(loc);
}
};
@Override
public void recordLocation(Location loc) {
service.onLocationChanged(loc);
}
}
public long startNewTrack() {
Log.d(MyTracksConstants.TAG, "TrackRecordingService.startNewTrack");