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;
    }   

}

私は 2 つのアクティビティでこのサービスにバインドしています。最初のアクティビティでは、サービスを開始しています:

    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 マークがデバイス画面から消えます。

ただし、2 番目のアクティビティ (userLocation を取得している場所) を入力し、その後 (Android の [戻る] ボタンを使用して) 両方を閉じると、GPS マークがまだ画面に表示されます!

2 番目のアクティビティのコード:

    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は、接続がないときにサービスが自動的に終了することを必ずしも意味するわけではありません。システムがリソースを必要とする場合、それがチョッピングブロックの最初のものであることを意味します。システムのリソースが不足していない場合は、サービスの実行を継続できます。アクティビティでサービスが再度必要になった場合、既存のインスタンスにバインドする方が、最初から作成するよりも時間的にコストがかからないためです。

要するに、それは「実行中」を続けますが、それについて心配する必要はありません-それは他の場所で必要とされるものを何も消費していません。

編集:また、サービスから解放されたからといって、サービスが非同期で処理している実行中の処理タスクを中断することを意味するわけではないことにも注意してください。起こったのは、結果にもう興味がないことをOSに伝えたことだけです。サービスから切断する前に、実行中のタスクを明示的に停止する必要があります。そうしないと、そのタスクはCPU時間を消費し続けます。

于 2012-04-04T20:29:10.023 に答える