以下のコードを一見すると、mLocationManager
オブジェクトは終了後にスコープ外に出る必要がonCreate(...)
あり、期待される動作はonLocationChanged
、オブジェクトがガベージ コレクションされるまで呼び出されないか、数回呼び出されることです。ただし、によって返されるオブジェクトはgetSystemService
、の範囲外にあるシングルトンのようですMainActivity
(システムサービスであるため、適切にそうです:))
ヒープ ダンプを取得し、Eclipse メモリ アナライザーで調べたところ、ContextImpl が LocationManager インスタンスへの参照を保持しているようです。メモリ ダンプには LocationManager オブジェクトへの参照が 2 つありましたが、コードには明らかに 1 つしかありません。これは、別の参照が別の場所に作成されていることを意味します。
私の質問は次のとおりです。
次の実装を呼び出すときに正確に何が起こっているかについて、誰かが完全な説明を持っていますか?
public abstract Object getSystemService(String name);
遅延作成されたシングルトンが返されたオブジェクトであり、参照が作成/保持されている正確な場所はどこですか?
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;
}
}
アップデート1
はLocationManager
シングルトンとして作成されます
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