4

我使用 Google Maps Api V2 在 android 中编写了一个应用程序。该应用程序基本上在后面运行一个服务,并将位置报告给使用 SupportMapFragment 添加 Google 地图的 Activity。

当我启动该应用程序时,一切似乎都运行良好并且地图已更新。问题是当我按下返回按钮或屏幕关闭并返回应用程序时 Google Maps 停止工作。Location 仍然被报告,我在 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 地图不会移动相机。

4

1 回答 1

1

我认为您的问题与非静态内部类有关CallBack。当您的活动被重新创建时,您在 中保留对它的静态引用myCallBack,它本身具有您的旧的隐式引用Activity。这不仅是内存泄漏,而且当您调用CallBack它时,它正在查看旧活动的变量。有关内存泄漏和非静态内部类的更多信息,请参阅这篇文章。

如果您Callback在启动新活动时创建新活动,它应该可以解决问题。所以,在你的InitializeActivity, 改变

 if(myCallback == null)
        myCallback = new MyHandlerCallback();

myCallback = new MyHandlerCallback();
于 2013-01-14T17:31:19.870 回答