Android服务:活动 - 服务沟通的良好实践

时间:2016-10-24 16:43:43

标签: android android-activity service

在我的Android应用程序中,我在'Service'类中使用'LocationService'。有几个教程推荐这种做法 跨活动的永久位置检查。然而,尽管有一些很好的文档,我仍然有一个问题 活动与我的服务之间的沟通。

这是我的LocationService类:

public class LocationService extends Service {

    public static  LocationManager locationManager;
    public static  LocationListener listener;
    private static Location currentLocation = null;

    @Override
    public void onCreate() {
        super.onCreate();
    }

     @Override
     public void onStart(Intent intent, int startId) {

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        listener = new LocationListener() {

           @Override
           public void onLocationChanged(Location location) {
               currentLocation = location;
               System.out.println("Current Location: " + currentLocation);
           }

           @Override
           public void onStatusChanged(String s, int i, Bundle bundle) {
           }

           @Override
           public void onProviderEnabled(String s) {
           }

           @Override
           public void onProviderDisabled(String s) {
           }
       };
   }

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

    @Override
    public void onDestroy() {
        locationManager.removeUpdates(listener);
    }

    public static Location getCurrentLocation() {
        return currentLocation;
    }

这是我全球课程的一部分:

...
@Override
public void onCreate() {
    super.onCreate();

    if(!LocationService.isRunning()) {
        Intent intent = new Intent(this, LocationService.class);
        startService(intent);
    }
}
...

这是我的Activity类:

public class ScreenActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.screen);
    }

    if (usesPosition) {
        Location tLoc = LocationService.getCurrentLocation();
        TextView t = (TextView) findViewById(R.id.tv);
        t.setText(tLoc.toString());
    }
}

我觉得这不是一种优雅的方式,甚至可能是错误的。我确实得到了一个好位置,但我觉得我没有访问该服务,但是 而是像静态类一样对待它。我还不熟悉将活动绑定到活动的概念,所以我想知道我是否确实需要 这样做。

编辑1

感谢您的第一个答案!这对我有点帮助了。这是我的Activity类的一部分:

private ServiceConnection locationServiceConnection = new ServiceConnection() {
    @Override
    public void onServiceDisconnected(ComponentName name) {
        locationServiceBound = false;
        System.out.println("Service disconnected");
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        com.ma.sainz.geoobserver.Tools.Services.LocationService.MyBinder myBinder = (com.ma.sainz.geoobserver.Tools.Services.LocationService.MyBinder) service;
        locationService = myBinder.getService();
        locationServiceBound = true;
        System.out.println("Service bound");
    }
};

其中myBinderLocationService中定义的类。 这是我的新onStart() - 我的活动方法:

@Override
protected void onStart() {
    super.onStart();

    Intent locationServiceIntent = new Intent(this, com.ma.sainz.geoobserver.Tools.Services.LocationService.class);
    bindService(locationServiceIntent, locationServiceConnection, Context.BIND_AUTO_CREATE);
    locationService.requestBackgroundLocation();
    System.out.println("onStart");
}

startService(locationServiceIntent)已在之前的活动中完成。

但是,locationService暂时为null。所以服务连接需要一些时间。我如何知道服务何时连接?

假设我想实现LocalBroadcast,那么除了服务实现之外还会这样吗?你有关于如何开始的提示吗?因为如果我们在他们出现的时候立即发送locationUpdates,我就不会费心等待服务连接。

2 个答案:

答案 0 :(得分:1)

你所拥有的并不是一个非常好的设计。想一想:通常你不仅要获得一个位置,还要保持更新。这意味着在发生此类更新时应通知您的活动。

你在这里有几个选择:

  1. 绑定服务并对其执行常规方法调用(获取位置,注册/取消注册侦听器)
  2. 使用LocalBroadcastManager以便从“服务转移到活动”广播位置更新
  3. 使用一些活动总线(我最喜欢的 - GreenRobot的EventBus),以便从服务活动广播位置更新
  4. 我个人使用后一种方法:服务在位置更新时将“粘性”事件发布到事件总线,活动在onResume()中查询这些事件并订阅更新。这样您的Service就不需要一直运行 - 在需要位置时启动它,获得所需精度的位置,并停止服务以免耗电。

答案 1 :(得分:0)

是的,不要这样做 - 它不是没有优雅,但也会导致内存泄漏。 Android服务可以绑定到其他组件,请参阅:https://developer.android.com/guide/components/bound-services.html。 您的actvity或其他服务将绑定到您的位置服务并使用ServiceProvides接口。请注意,当至少保留一个连接时,服务将运行。启动并绑定到服务,然后它将一直运行,直到你停止它,你将能够使用Binder的该服务的显式接口。 另一个很好的技术 - 使用EventBus(greenRobot)在Activity和Service之间传递粘性事件。事件将等到另一个组件初始化并接收该事件。您可以订阅该事件并在onPause和onResume方法中取消订阅。

相关问题