我使用Google Maps Api V2在Android上编写了一个应用程序。该应用程序基本上运行一个服务,并使用SupportMapFragment向使用SupportMapFragment添加Google Map的活动报告位置。
当我启动应用程序时,一切似乎都运行正常,地图也会更新。问题是当我按下按钮或屏幕关闭并返回App谷歌地图停止工作。仍然会报告位置,我在Map对象上调用moveCamera方法。
public class GpsTracker extends android.support.v4.app.FragmentActivity {
public static final int GPS_LOCATION_UPDATE = 0;
public static final int NETWORK_LOCATION_UPDATE = 1;
public static final int LOCATION_NETWORK_UNAVAILABLE = 2;
public static final int LOCATION_GPS_UNAVAILABLE = 3;
private static String gpsTrackerTag = "GpsTracker:MainActivity";
private GoogleMap mMap;
private PolylineOptions mpolyOptions = new PolylineOptions();
GpsTrackerMyService myservice = null;
ServiceConnection sc = null;
static MyHandlerCallback myCallback = null;
//private Boolean mServiceRunning = false; // Initial State When service is yet not started.
private Boolean mServiceBinded = false;
public static Callback CallBackHandler()
{
return myCallback;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gps_tracker);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
if (savedInstanceState == null) {
// First incarnation of this activity.
mapFragment.setRetainInstance(true);
} else {
// Reincarnated activity. The obtained map is the same map instance in the previous
// activity life cycle. There is no need to reinitialize it.
mMap = mapFragment.getMap();
}
InitializeActivity();
setUpMapIfNeeded();
}
@Override
protected void onPause()
{
super.onPause();
if(mServiceBinded)
{
unbindService(sc);
mServiceBinded = false;
Log.d(gpsTrackerTag, "onPause(): Unbinded from the Serivce");
}
else
Log.d(gpsTrackerTag, "onPause(): Service Already in not Bind State");
}
@Override
protected void onResume()
{
super.onResume();
if(GpsTrackerMyService.isInstanceCreated() == true)
{
bindService(new Intent(this, GpsTrackerMyService.class), sc, 0);
mServiceBinded = true;
Log.d(gpsTrackerTag, "onResume(): Binded to the Service");
}
else
Log.d(gpsTrackerTag, "onResume(): Service Not Running");
setUpMapIfNeeded();
}
@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_gps_tracker, menu);
return true;
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
// mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
private void InitializeActivity() {
if(myCallback == null)
myCallback = new MyHandlerCallback();
if(sc == null){
sc = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
mServiceBinded = false;
CharSequence text = "Service DisConnected";
Toast t = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG);
t.show();
Log.d(gpsTrackerTag, "Service Disconnected ");
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myservice = ((MyBinder) service).getService();
mServiceBinded = true;
Log.d(gpsTrackerTag, "Service Connected ");
}
};
}
}
public void startButton_Click(View view)
{
if(GpsTrackerMyService.isInstanceCreated() == false)
{
Intent serviceIntent = startService();
bindService(serviceIntent);
Log.d(gpsTrackerTag, "startButton_Click(): Service Started and Called for bind");
}
else
Log.d(gpsTrackerTag, "startButton_Click(): Service Already Running");
}
private void bindService(Intent serviceIntent) {
bindService(serviceIntent, sc, 0 );
}
private Intent startService() {
Intent serviceIntent = new Intent(this, GpsTrackerMyService.class);
startService(serviceIntent);
return serviceIntent;
}
public void stopButton_Click(View view)
{
stopService();
}
private void stopService() {
if(GpsTrackerMyService.isInstanceCreated() == true)
{
Log.d(gpsTrackerTag, "stopService(): Service Running Calling Stop on the Service");
myservice.stopSelf();
}
else
Log.d(gpsTrackerTag, "stopService(): Service Already Stopped");
}
public class MyHandlerCallback implements Callback
{
@Override
public boolean handleMessage(Message arg0) {
Location l;
CharSequence text;
Toast t;
LatLng mLatLng;
int pos = 1;
switch(arg0.what)
{
case GpsTracker.LOCATION_NETWORK_UNAVAILABLE:
text = "Network Location Unavailable";
t = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG);
t.show();
return true;
case GpsTracker.NETWORK_LOCATION_UPDATE:
l = ((Location)arg0.obj);
mLatLng = new LatLng(l.getLatitude(), l.getLongitude());
mpolyOptions.add(mLatLng).width(2).color(Color.BLACK).geodesic(true);
mMap.addPolyline(mpolyOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mLatLng, 12));
mMap.addMarker(new MarkerOptions()
.position(mLatLng)
.title("Pos " + pos));
//text = ((Location)arg0.obj).toString();
t = Toast.makeText(getApplicationContext(), "Network Location Update", Toast.LENGTH_LONG);
t.show();
return true;
case GpsTracker.GPS_LOCATION_UPDATE:
l = ((Location)arg0.obj);
mLatLng = new LatLng(l.getLatitude(), l.getLongitude());
//mpolyOptions.add(mLatLng).width(2).color(Color.BLACK).geodesic(true);
//mMap.addPolyline(mpolyOptions);
boolean check = mMap.isMyLocationEnabled();
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mLatLng, 12));
//text = ((Location)arg0.obj).toString();
t = Toast.makeText(getApplicationContext(), "GPS Location Update", Toast.LENGTH_LONG);
t.show();
return true;
case GpsTracker.LOCATION_GPS_UNAVAILABLE:
text = "Gps Location Unavailable";
t = Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG);
t.show();
return true;
default:
return false;
}
}
}
在MyCallBackHandler案例GPS_LOCATION_UPDATE中,地图不会移动相机。
答案 0 :(得分:1)
我认为您的问题与非静态内部类CallBack
有关。重新创建活动后,您会在myCallBack
中保留对其的静态引用,该引用本身具有对旧Activity
的隐式引用。这不仅是内存泄漏,而且当您调用CallBack
时,它正在查看旧活动的变量。有关内存泄漏和非静态内部类的更多信息,请参阅this post。
如果您在启动新活动时创建新的Callback
,则应该可以解决问题。因此,在InitializeActivity
中,更改
if(myCallback == null)
myCallback = new MyHandlerCallback();
到
myCallback = new MyHandlerCallback();