На первый взгляд в коде ниже объект mLocationManager
должен выйти из области видимости после завершения onCreate(...)
, и ожидаемое поведение заключается в том, что onLocationChanged
никогда не вызывается или не вызывается несколько раз, пока объект не будет собран мусором, Однако объект, возвращаемый getSystemService
, кажется, является одиночным, который живет за пределами области MainActivity
(соответственно, так как это системная служба:))
После того, как вы взяли кучу кучи и пропустили его с помощью Eclipse Memory Analyzer, похоже, что ContextImpl хранит ссылку на экземпляр LocationManager. В дампе памяти были две ссылки на объект LocationManager, тогда как в коде есть только одно, что означает, что другая ссылка создается где-то в другом месте.
Мои вопросы:
Есть ли у кого-то полное описание того, что именно происходит при вызове реализации:
public abstract Object getSystemService(String name);
является ли объект возвращенным singleton lazily created и где именно ссылка создана/сохранена?
package com.neusoft.bump.client.storage;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("TAG", "STARTED");
LocationManager mLocationManager = (LocationManager) this
.getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
Log.v("TAG", "onLocationChanged");
Log.v("TAG", "Latitude: " + location.getLatitude()
+ "Longitude: " + location.getLongitude());
}
public void onStatusChanged(String provider, int status,
Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
// Register the listener with the Location Manager to receive location
// updates
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
600, 0, locationListener);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Update1
LocationManager
создается как singleton
private LocationManager getLocationManager() {
synchronized (sSync) {
if (sLocationManager == null) {
IBinder b = ServiceManager.getService(LOCATION_SERVICE);
ILocationManager service = ILocationManager.Stub.asInterface(b);
sLocationManager = new LocationManager(service);
}
}
return sLocationManager;
}
но мне трудно понять, что происходит при вызове ServiceManager.getService(LOCATION_SERVICE);
даже после чтения кода ServiceManager
.