Friday, October 7, 2011

Android Service Introduction and Example







Service Introduction

A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.

A service can essentially take two forms:

Started
A service is "started" when an application component (such as an activity) starts it by calling startService(). Once started, a service can run in the background indefinitely, even if the component that started it is destroyed. Usually, a started service performs a single operation and does not return a result to the caller. For example, it might download or upload a file over the network. When the operation is done, the service should stop itself.
Bound
A service is "bound" when an application component binds to it by calling bindService(). A bound service offers a client-server interface that allows components to interact with the service, send requests, get results, and even do so across processes with interprocess communication (IPC). A bound service runs only as long as another application component is bound to it. Multiple components can bind to the service at once, but when all of them unbind, the service is destroyed.

Although this documentation generally discusses these two types of services separately, your service can work both ways—it can be started (to run indefinitely) and also allow binding. It's simply a matter of whether you implement a couple callback methods: onStartCommand() to allow components to start it and onBind() to allow binding.


Basic:

To create a service, you must create a subclass of Service (or one of its existing subclasses). In your implementation, you need to override some callback methods that handle key aspects of the service lifecycle and provide a mechanism for components to bind to the service, if appropriate. The most important callback methods you should override are:

onStartCommand()
The system calls this method when another component, such as an activity, requests that the service be started, by calling startService(). Once this method executes, the service is started and can run in the background indefinitely. If you implement this, it is your responsibility to stop the service when its work is done, by calling stopSelf() or stopService(). (If you only want to provide binding, you don't need to implement this method.)
onBind()
The system calls this method when another component wants to bind with the service (such as to perform RPC), by calling bindService(). In your implementation of this method, you must provide an interface that clients use to communicate with the service, by returning anIBinder. You must always implement this method, but if you don't want to allow binding, then you should return null.
onCreate()
The system calls this method when the service is first created, to perform one-time setup procedures (before it calls eitheronStartCommand() or onBind()). If the service is already running, this method is not called.
onDestroy()
The system calls this method when the service is no longer used and is being destroyed. Your service should implement this to clean up any resources such as threads, registered listeners, receivers, etc. This is the last call the service receives.

If a component starts the service by calling startService() (which results in a call to onStartCommand()), then the service remains running until it stops itself with stopSelf() or another component stops it by calling stopService().

If a component calls bindService() to create the service (and onStartCommand() is not called), then the service runs only as long as the component is bound to it. Once the service is unbound from all clients, the system destroys it.

The Android system will force-stop a service only when memory is low and it must recover system resources for the activity that has user focus. If the service is bound to an activity that has user focus, then it's less likely to be killed, and if the service is declared to run in the foreground (discussed later), then it will almost never be killed. Otherwise, if the service was started and is long-running, then the system will lower its position in the list of background tasks over time and the service will become highly susceptible to killing—if your service is started, then you must design it to gracefully handle restarts by the system. If the system kills your service, it restarts it as soon as resources become available again (though this also depends on the value you return from onStartCommand(), as discussed later). For more information about when the system might destroy a service, see the Processes and Threading document.

In the following sections, you'll see how you can create each type of service and how to use it from other application components.

Declaring a service in the manifest

Like activities (and other components), you must declare all services in your application's manifest file.

To declare your service, add a element as a child of the element. For example:

<manifest ... >
  ...
<application ... >
<service android:name=".ExampleService" />
...
</application>
</manifest>

There are other attributes you can include in the element to define properties such as permissions required to start the service and the process in which the service should run. Theandroid:name attribute is the only required attribute—it specifies the class name of the service. Once you publish your application, you should not change this name, because if you do, you might break some functionality where explicit intents are used to reference your service (read the blog post, Things That Cannot Change).

See the element reference for more information about declaring your service in the manifest.

Just like an activity, a service can define intent filters that allow other components to invoke the service using implicit intents. By declaring intent filters, components from any application installed on the user's device can potentially start your service if your service declares an intent filter that matches the intent another application passes to startService().

If you plan on using your service only locally (other applications do not use it), then you don't need to (and should not) supply any intent filters. Without any intent filters, you must start the service using an intent that explicitly names the service class.

Simple Example:

Create a Service Run for 5 seconds.

1. Create main.xml with two button named button1 and button2.

2. Create a java Class TestActivity.java. extends from Activity.

3. Create one more java class ServiceMsg.java extends from Service.

4. Manifeat entry for service within application tag.

<service android:name=".ServiceMsg"/>


Source code of TestActivity.class

package com.PackageName;

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

public class TestActivity extends Activity {

/** Called when the activity is first created. */

Button btnstart;

Button btnstop;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

btnstart=(Button)findViewById(R.id.button1);

btnstop=(Button)findViewById(R.id.button2);

final Intent myIntent = new Intent(getApplicationContext(), ServiceMsg.class);

btnstart.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {

myIntent.putExtra("extraData", "somedata");

startService(myIntent);

}

});

btnstop.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

stopService(myIntent);

}

});

}

}

Source Code of ServiceMsg.class

package com.PackageName;

import android.app.Service;

import android.content.Intent;

import android.os.IBinder;

import android.util.Log;

import android.widget.Toast;

public class ServiceMsg extends Service{

String s="Tag";

@Override

public IBinder onBind(Intent intent) {

// TODO Auto-generated method stub

return null;

}

@Override

public void onCreate() {

// TODO Auto-generated method stub

super.onCreate();

Log.i(s, "Service Created");

}

@Override

public void onDestroy() {

// TODO Auto-generated method stub

super.onDestroy();

Toast.makeText(ServiceMsg.this,"Service End",2).show();

}

@Override

public void onStart(Intent intent, int startId) {

// TODO Auto-generated method stub

super.onStart(intent, startId);

Toast.makeText(this,"Service Started",2).show();

new Thread(new Runnable() {

@Override

public void run() {

performServiceTask();

}

}).start();

}

public void performServiceTask()

{

//Service will run for 5 seconds.

try {

Thread.sleep(5000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

stopSelf(); //we can stop service by stopSelf() or from the Activity by calling stopService(Intent);

}

}

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:text="Start Service" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
<Button android:text="Stop Service" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
</LinearLayout>




No comments:

Post a Comment