Good practice for Android services

I am currently using 2 services in my application:

1: LocationService basically tries to localize the user and strives to stay alive only when the application is in the foreground.

2: XmppService , which initiates a connection to the xmpp server, receives messages, sends them, logs out of the system ... and seeks to stay alive until the user logs out.

I read quite a lot of documentation, but I just can't figure it out.

I have Leaks when I try to save the LocationServiceBinder link, which is used to call my service functions (using AIDL interfaces). The same goes for Xmpp. When I untie, I sometimes get ANRs (which seem to be related to the fact that my bind / unbind are weird, onResume, onRestart ...).

The whole system works , but I’m sure that this is the wrong way to do this, and please, I would like after experienced people to return to the right side of the force! :)

Greetings

UPDATE

My location service contacts when the application starts, in order to complete the user position as quickly as possible:

if(callConnectService == null) { callConnectService = new ServiceConnection() { public void onServiceConnected(ComponentName name, IBinder binder) { locationServiceBinder = LocationServiceBinder.Stub.asInterface(binder); try { global.setLocationBinder(locationServiceBinder); global.getLocationBinder().startLocationListener(); } catch (Exception e){ Log.e(TAG, "Service binder ERROR"); } } public void onServiceDisconnected(ComponentName name) { locationServiceBinder = null; } }; } /* Launch Service */ aimConServ = new Intent(this, LocationService.class); boolean bound = bindService(aimConServ,callConnectService,BIND_AUTO_CREATE); 

My XMPp service starts when a user logs in:

callConnectService = new ServiceConnection () {

  public void onServiceConnected(ComponentName name, IBinder binder) { try { Log.d(TAG, "[XMPP_INIT] Complete."); global.setServiceBinder(ConnectionServiceBinder.Stub.asInterface(binder)); //Connect to XMPP chat global.getServiceBinder().connect(); } catch (Exception e){ Log.e(TAG, "Service binder ERROR "); e.printStackTrace(); } } public void onServiceDisconnected(ComponentName name) { Log.e(TAG, "Service binder disconnection "); } }; /* Launch Service */ Intent aimConServ = new Intent(MMWelcomeProfile.this, XmppService.class); bound = bindService(aimConServ,callConnectService,Context.BIND_AUTO_CREATE); 

and unlink each operation:

 if (callConnectService != null){ unbindService(callConnectService); callConnectService = null; } 
+2
android service geolocation xmpp
01 Dec '11 at 12:59
source share
3 answers

It was not well documented in the official Google Developers Guide, Context.bindService () is actually an asynchronous call. It is for this reason that ServiceConnection.onServiceConnected () is used as a callback method, which means it did not happen right away.

 public class MyActivity extends Activity { private MyServiceBinder myServiceBinder; protected ServiceConnection myServiceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { myServiceBinder = (MyServiceBinderImpl) service; } ... ... } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // bindService() is an asynchronous call. myServiceBinder is resoloved in onServiceConnected() bindService(new Intent(this, MyService.class),myServiceConnection, Context.BIND_AUTO_CREATE); // You will get a null point reference here, if you try to use MyServiceBinder immediately. MyServiceBinder.doSomething(); // <-- not yet resolved so Null point reference here } } 

A workaround is to call MyServiceBinder.doSomething () in myServiceConnection.onServiceConnected () or to execute MyServiceBinder.doSomething () using some kind of user interaction (like pressing a button), like lagging after calling bindService (), and before the system will get the myServiceBinder link pretty soon. if you do not use it immediately, you should be fine.

Submit this question to CommonsWare for more details.

+1
Dec 01 '11 at
source share
— -

this branch is quite old, but I just discovered it.

In fact, there is only one way for your service to continue to live if it is connected: it must also be started. The documentation is not entirely clear, but the service can be started and linked.

In this case, the service will not be destroyed when you untie it, it will be destroyed when:

  • you stop him and no one is connected with him.
  • you untied him, and he was stopped earlier.

I made a small demo Service Lifecycle application on GitHub and it is also available on Google Play .

Hope that helps;)

0
Nov 21
source share

if you attach to a service in Activity, you also need to unlock it:

 @Override protected void onResume() { Log.d("activity", "onResume"); if (locationServiceBinder == null) { doBindLocationService(); } super.onResume(); } @Override protected void onPause() { Log.d("activity", "onPause"); if (locationServiceBinder != null) { unbindService(callConnectService); locationServiceBinder = null; } super.onPause(); } 

where doBindLocationService ():

 public void doBindLocationService() { Log.d("doBindService","called"); aimConServ = new Intent(this, LocationService.class); // Create a new Messenger for the communication back // From the Service to the Activity bindService(aimConServ, callConnectService, Context.BIND_AUTO_CREATE); } 

You also need to follow this practice for your XmppService.

0
Dec 27 '12 at 16:13
source share



All Articles