Android Example: Communication between Activity and Service using Messaging
I recently wrote my first little app for my Android smartphone and I was surprised how easy it was. Being familiar with regular Java, learning the new Android APIs was very simple for the most part. However, there was one thing that wasn’t particularly straight forward: communicating between an Activity, i.e. the user interface, and a background Service started by the application. After many hours, I found some sample code on Stack Overflow which I used to create a very generic reusable solution to start, stop and communicate with your own Service implementation.
The code below provides an easy way to:
Implement your own Android background
ServiceStart and stop the service from an
Activity, i.e. the UISend/receive messages by the
ServiceSend/receive messages by the
Activity
Solution
Here are three simple steps how to use my code:
- Download and import the two Java classes
AbstractServiceandServiceManager - Inherit from
AbstractServiceto implement your own service. - Add a
ServiceManagerto your Activity.
You can now:
- Control the service with ServiceManager.start() and .stop()
- Send messages to the service via ServiceManager.send()
- Receive messages from the service by passing a Handler in the ServiceManager constructor
- Send messages from the service to all listeners using AbstractService.send()
- Receive messages in the service via the onReceiveMessage() callback
Example
Here is a small excerpt that shows how to use the code, i.e. how to implement your service and control it from the activity. You can find a full example on Launchpad.
Step 1: Inherit fromAbstractService: Override onStartService, onStopService and onReceiveMessage, and use send() to send messages to the activity.
public class SomeService1 extends AbstractService {
public static final int MSG_INCREMENT = 1;
public static final int MSG_COUNTER = 2;
private Timer timer = new Timer();
private int counter = 0, incrementby = 1;
@Override
public void onStartService() {
// Increment counter and send to activity every 250ms
timer.scheduleAtFixedRate(new TimerTask(){
public void run() {
try {
counter += incrementby;
send(Message.obtain(null, MSG_COUNTER, counter, 0));
}
catch (Throwable t) { }
}, 0, 250L);
}
}
@Override
public void onStopService() {
if (timer != null) {timer.cancel();}
counter = 0;
}
@Override
public void onReceiveMessage(Message msg) {
if (msg.what == MSG_INCREMENT) {
incrementby = msg.arg1;
}
}
}
Step 2: Use the service in an activity with aServiceManager: Instantiate a service manager, control the service with .start()/.stop() and send messages to the service with .send(). Note: To unregister the activity from the service, you should call .unbind() in the onDestroy()-callback.
public class ExampleActivity extends Activity {
private ServiceManager service;
@Override
public void onCreate(Bundle savedInstanceState) {
// Create a service 'SomeService1' (see below) and handle incoming messages
this.service = new ServiceManager(this, SomeService1.class, new Handler() {
@Override
public void handleMessage(Message msg) {
// Receive message from service
switch (msg.what) {
case SomeService1.MSG_COUNTER:
textValue1.setText("Counter @ Service1: " + msg.arg1);
break;
default:
super.handleMessage(msg);
}
}
});
// Now you can control the service via .start(), .stop()
service.start();
service.stop();
// Or send messages to it
service.send(Message.obtain(null, SomeService1.MSG_VALUE, 12345, 0));
}
@Override
protected void onDestroy() {
super.onDestroy();
try { service.unbind(); }
catch (Throwable t) { }
}
...
}
Full code example
Checkout on Launchpad:
https://code.launchpad.net/~binwiederhier/+junk/android-service-example
Browse code on Launchpad:
http://bazaar.launchpad.net/~binwiederhier/+junk/android-service-example/files