1

我实现了用于监听用户位置的 Android 服务:

public class ListenLocationService extends Service {
    IBinder mBinder = new LocalBinder();      
    public interface ILocationService {     
          Location userLocation = new Location("");
          public void StartListenLocation();
          public void StopListenLocation();
          public Location getUserLocation();
        }
    LocationManager locationManager;
    LocationListener locationListener;
    public class LocalBinder extends Binder implements ILocationService{

        public void StopListenLocation(){
            //so many attempts to stop service and no one helped
            locationManager.removeUpdates(locationListener);
            locationListener = null;
            stopSelf();
        }

        public void StartListenLocation()
        {   
            locationManager = (LocationManager)ListenLocationService.this.getSystemService(Context.LOCATION_SERVICE);
            locationListener = new LocationListener() {

                public void onStatusChanged(String provider, int status, Bundle extras) {               
                }       

                public void onProviderEnabled(String provider) {                     
                }

                public void onProviderDisabled(String provider) {                   
                }

                public void onLocationChanged(Location location) {                  
                    userLocation.set(location);
                }
            };
            //if I have only one requestLocationUpdates situation is the same

                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 
                        400, 1, locationListener);
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 
                        400, 1, locationListener);
            }

        public Location getUserLocation(){
            return userLocation;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }   

}

我在两个活动中绑定到这个服务。在第一个活动中,我只是启动服务:

    private ServiceConnection mConnection = new ServiceConnection() {

        public void onServiceConnected(ComponentName className,
                IBinder service) {
            mService = (ILocationService) service; 
            mService.StartListenLocation();   
        }

        public void onServiceDisconnected(ComponentName arg0) {
            Log.d("LOG","onServiceDisconnected");
        }
    };

    public void onCreate(Bundle savedInstanceState) {
...
        Intent intent = new Intent(this, ListenLocationService.class);
        bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
...
}
    @Override 
    public void onStop(){
        super.onStop();
        unbindService(mConnection);
        mService.StopListenLocation();      
    }

如果我只在我的应用程序中启动第一个活动并关闭它然后服务停止 - GPS 标记从设备屏幕上消失。

但是,如果我进入第二个活动(我正在获取 userLocation)并在此关闭之后(使用 Android 后退按钮),那么 GPS 标记仍在我的屏幕上!

第二个活动的代码:

    private ServiceConnection mConnection = new ServiceConnection() {

        public void onServiceConnected(ComponentName className,
                IBinder service) {
            mService = (ILocationService) service;             
            userLocation = mService.getUserLocation();              
        }

        public void onServiceDisconnected(ComponentName arg0) {
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
...
    Intent intent = new Intent(this, ListenLocationService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
...
}
    @Override 
    public void onStop(){
        super.onStop();
            unbindService(mConnection);
            mService.StopListenLocation();          

    }

你可以看到我onStop()不仅在这两种方法中都写了unbindService(最初我认为这就足够了),而且我正在StopListenLocation用这段代码调用函数:

locationManager.removeUpdates(locationListener);
locationListener = null;
stopSelf();

如果只有第一个活动绑定到它,它会停止服务。但是,如果两个活动都被绑定,则服务不会在两者之后停止onStop()。我曾经Log.d确保所有方法都被调用:onStop(), stopListenLocation(), onBind()等等。唯一的事情是onServiceDisconnected()永远不会被调用。

我想情况是我的服务启动了另一个系统服务来监听位置。我停止了我的服务,但这个控制 GPS 的系统服务继续工作,尽管locationManager.removeUpdates(locationListener);. 也许我的建议有误。

如何在两个活动都停止的情况下停止 GPS?

4

1 回答 1

2

BIND_AUTO_CREATE 并不一定意味着服务将在没有连接时自行终止,它只是意味着如果系统需要资源,它是第一件事。如果系统没有资源匮乏,它将让您的服务继续运行,因为如果您的活动再次需要该服务,那么绑定到现有实例比从头开始创建它在时间上更便宜。

简而言之,它会继续“运行”,但不要担心——它不会消耗其他地方需要的任何东西。

编辑:另请注意,仅仅因为您未绑定服务并不意味着它将中断服务正在异步处理的任何正在运行的处理任务。所发生的只是你告诉操作系统你不再对结果感兴趣了。您必须在与服务断开连接之前明确停止任何正在运行的任务,否则该任务将继续消耗 CPU 时间

于 2012-04-04T20:29:10.023 回答