20-b Local Service

20.2 Local Service

Service is a fundamental component in Android. Often, applications will need to run processes for a long time without any intervention from the user, or very rare interventions. These background processes need to keep running even when the phone is being used for other activities.

To accommodate for such a requirement, android has introduced the Service component. It is a long lived component and does not implement any user interface of its own.

Typically a user interacts with a service through an activity that has a UI. The service by itself notifies the user in case of any need for user intervention.

In this article, we'll make a very simple service which runs in the background but does not have any notification features.

In order to start and stop the service, an activity called the service provider will be created.

In this example, when the service starts, it toasts a message that the service has started. When the service ends, it toasts a message that the service has ended. This is not of much use in the real sense of services. However, it simplifies the introduction of service creation and destruction.

Ideally, one of the ways could be: a service that is running should notify itself as running by putting up a status bar notification as discussed in the previous section. And when the service has completed running the notification can be removed. Through the notification, the service can give a user interface for binding to the service or viewing the status of the service or any other similar interaction with the service. The combination of service with notification will be an example I will given in the next section.

Let's talk a little bit more about services.

Binding to a service 
Once a service has begun and is running in the background, any number of activities can �bind� to the service. In fact, if we want to bind to a service that has not started, calling to bind could initiate the service. Such a service would shut down as soon as the last user detaches from the service.

Remote service 
The services defined above are those that run in the same process as the application that started it. However, we can have services that run in its own process. This is particularly useful when the service has to run for a long time, typical example being a background music player. For two processes to communicate, the object being passed needs to be marshaled.

For this, Android provides a AIDL tool (Android Interface Definition Language) to handle all marshalling and communication. The remote service example will be taken up in a subsequent article.

Most confusion about the Service class actually revolves around what it is not rather than what it is:

  • A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
  • A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).

Thus a Service itself is actually very simple, providing two main features:

  • A facility for the application to tell the system about something it wants to be doing in the background (even when the user is not directly interacting with the application). This corresponds to calls to Context.startService(), which ask the system to schedule work for the service, to be run until the service or someone else explicitly stop it.
  • A facility for an application to expose some of its functionality to other applications. This corresponds to calls toContext.bindService(), which allows a long-standing connection to be made to the service in order to interact with it.

When a Service component is actually created, for either of these reasons, all that the system actually does is instantiate the component and call its onCreate() and any other appropriate callbacks on the main thread. It is up to the Service to implement these with the appropriate behavior, such as creating a secondary thread in which it does its work.

Finally the Service Example.

  1. Let us start with creating a service class that extends android.app.Service. This service just displays a message when started and again displays a message when stopped. Hence the onStart() and onDestroy() methods are implemented. Here is the code.
    package com.bogotobogo.serviceprovider;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.widget.Toast;
    
    public class SimpleService extends Service {
    
    	@Override
    	public IBinder onBind(Intent arg0) {
    		return null;
    	}
    
    	@Override
    	public void onCreate() {
    		super.onCreate();
    		Toast.makeText(this,"Service created", Toast.LENGTH_LONG).show();
    	}
    	
    	@Override
    	public void onDestroy() {
    		super.onDestroy();
    		Toast.makeText(this,"Service destroyed", Toast.LENGTH_LONG).show();
    	}
    	
    	@Override
    	public void onStart(Intent intent, int startId) {
    		super.onCreate();
    		Toast.makeText(this,"Service started", Toast.LENGTH_LONG).show();
    	}
    }
    
    
  2. An entry for this service needs to be made in the AndroidManifest.xml file. Here it is:
    <service android:name=".SimpleService">
    </service>
    
  3. Now, we need to be able to invoke this service. i.e. start the service and stop the service. We choose to write an activity that can start and stop the service. This activity is called ServiceProvider. Here is what it does: 
    To start/stop the service � 
    		Button start = (Button)findViewById(R.id.startButton);
    		Button stop = (Button)findViewById(R.id.stopButton);
    	        
    		start.setOnClickListener(this);
    		stop.setOnClickListener(this);
    	}
    	
    	public void onClick(View src) {    
    		switch (src.getId()) {    
    			case R.id.startButton:        
    				startService(new Intent(this, SimpleService.class));      
    				break;    
    			case R.id.stopButton:          
    				stopService(new Intent(this, SimpleService.class));      
    				break;    
    		}  
    	}
    
  4. The entry for this class in the AndroidManifest.xml file is as usual:
    <activity android:name=".ServiceProvider"
    android:label="@string/app_name">
    <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    </activity>
    

Here is our Java files, ServiceProvider.java:

package com.bogotobogo.serviceprovider;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ServiceProvider extends Activity implements OnClickListener{

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	        
		Button start = (Button)findViewById(R.id.startButton);
		Button stop = (Button)findViewById(R.id.stopButton);
	        
		start.setOnClickListener(this);
		stop.setOnClickListener(this);
	}
	
	public void onClick(View src) {    
		switch (src.getId()) {    
			case R.id.startButton:        
				startService(new Intent(this, SimpleService.class));      
				break;    
			case R.id.stopButton:          
				stopService(new Intent(this, SimpleService.class));      
				break;    
		}  
	}
}

and SimpleService.java.

package com.bogotobogo.serviceprovider;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;

public class SimpleService extends Service {

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

	@Override
	public void onCreate() {
		super.onCreate();
		Toast.makeText(this,"Service created", Toast.LENGTH_LONG).show();
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		Toast.makeText(this,"Service destroyed", Toast.LENGTH_LONG).show();
	}
	
	@Override
	public void onStart(Intent intent, int startId) {
		super.onCreate();
		Toast.makeText(this,"Service started", Toast.LENGTH_LONG).show();
	}
}

Or we can have a slightly different ServiceProvideB.java file depending on the way how the Listener interface is implemented and another file SimpleService.java has been modified slightly so that it can play audio, synchronized with the start/stop button.

ServiceProvideB.java:

package com.bogotobogo.serviceproviderb;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class ServiceProviderB extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
	        
		Button start = (Button)findViewById(R.id.startButton);
		Button stop = (Button)findViewById(R.id.stopButton);
	        
        start.setOnClickListener(startListener);
        stop.setOnClickListener(stopListener); 
	}
   
	private OnClickListener startListener = new OnClickListener() {
		public void onClick(View v){
			startService(new Intent(ServiceProviderB.this,SimpleService.class));
		}	        	
	};
   
	private OnClickListener stopListener = new OnClickListener() {
		public void onClick(View v){
      		stopService(new Intent(ServiceProviderB.this,SimpleService.class));
		}	        	
	};
}

SimpleService.java

package com.bogotobogo.serviceproviderb;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.widget.Toast;

public class SimpleService extends Service {

	MediaPlayer player;
	@Override
	public IBinder onBind(Intent arg0) {
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		Toast.makeText(this,"Service created", Toast.LENGTH_LONG).show();
		player = MediaPlayer.create(this, R.raw.amanda);
	}
	
	@Override
	public void onDestroy() {
		super.onDestroy();
		Toast.makeText(this,"Service destroyed", Toast.LENGTH_LONG).show();
		player.stop();
	}
	
	@Override
	public void onStart(Intent intent, int startId) {
		super.onCreate();
		Toast.makeText(this,"Service started", Toast.LENGTH_LONG).show();
		player.start();
	}
}

Now we can launch this application and we can start and stop a service.


 

 

 

Files used in this Service example, ServiceProvider.zip 
or ServiceProviderB.zip


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小涵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值