转载自博客原文地址:http://blog.csdn.net/kongre/article/details/6741460
Service是没有用户界面的,在后台运行的Android Framework核心组件之一。Android支持两种Service:本地Service和远程Service。所谓的“本地Service”是指这种Service只能被当前应用程序访问,而不能被其他应用程序访问。那与之相对的“远程Service”不仅可以被当前的应用程序访问,还可以被不同进程当中的应用程序访问。远程Service通过使用Android
Interface Definition Language(AIDL)来实现不同进程当中对于Service的调用。
秘籍一、如何创建一个简单的Service
- public class TestService1 extends Service {
- private static final String TAG = "TestService1";
- @Override
- public void onCreate() {
- Log.d(TAG, "-->onCreate() method was invoked");
- super.onCreate();
- }
- @Override
- public IBinder onBind(Intent intent) {
- Log.d(TAG, "-->onBind() method was invoked");
- return null;
- }
- }
首先,定义的Service需要继承android.app.Service,然后需要在项目清单文件当中声明此Service。
- <service android:name="TestService1"></service>
PS:虽然这么一个Service没有任何实际的作用,但是不得不说定义一个Service就是这么的简单。
秘籍二、深入理解Android当中的Service
onCreate()方法是当Service第一次创建时由系统自动回调的一个方法,跟Activity的onCreate()的回调机制类似,主要可以用来做一些在Service启动的时候的初始化的操作。比如,我们可以在onCreate()方法当中启动一个后台线程,在onDestory()方法当中停止线程。调用Service的客户端可以通过两种方式来启动Service,分别为Context.startService()和Context.bindService()方法。注意:一般来讲,通过Context.startService()启动的Service都是本地的Service,而通过Context.bindService()启动的Service都是远程Service,但是也不一定,如果你的应用程序,比如说Activity需要跟本地Service做交互,那么你也只能采用Context.bindService()来启动本地Service。Android为什么提供Service这种机制?主要有两个原因,第一是允许开发者利用Service从而轻松的实现一些后台的任务处理,第二是允许开发者通过使用AIDL来实现进程间的交互。什么时候使用本地Service,什么时候使用远程Service?简单来说,如果某一个Service目的仅仅是为了在当前应用程序当中做一些后台任务,而其他应用程序当中不需要做这些任务的时候,那么这个Service就可以定义为本地Service,
而不用去实现onBind()方法。相反,如果某一个Service()的后台任务,不仅当前应用程序需要,其他应用程序也需要做此中后台任务,那么可以把这个Service定义为远程Service,实现服务的共享。
综上所述:不能仅仅通过客户端的调用方式来判断这个Service是属于本地Service还是远程Service。因为客户端如果需要与本地Service做一定的交互,也只能是通过Context.bindService()来启动服务,我们可以根据应用程序当中是否有相应的AIDL文件来进行判断,如果有相应的AIDL文件,则表明此Service是远程Service。如果没有,则表明此Service为本地Service。
秘籍三、理解本地Service
- public class BackgroundService extends Service {
- private NotificationManager notificationMgr;
- @Override
- public void onCreate() {
- super.onCreate();
- notificationMgr = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
- displayNotificationMessage("starting Background Services");
- Thread tr = new Thread(new ServiceWorker());
- tr.start();
- }
- class ServiceWorker implements Runnable{
- @Override
- public void run() {
- //do background processing here
- //stop when service when done
- //BackgroundService.this.stopSelf();
- }
- }
- private void displayNotificationMessage(String message) {
- Notification notification = new Notification(R.drawable.icon, message, System.currentTimeMillis());
- PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
- notification.setLatestEventInfo(this, "Background Service", message, contentIntent);
- notificationMgr.notify(R.id.app_notification_id, notification);
- }
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- displayNotificationMessage("stopping Background Service");
- }
- }
客户端如何调用本地Service:
- public class LocaleServiceActivity extends Activity {
- private static final String TAG = "LocaleServiceActivity";
- Button mBindBtn, mUnbindBtn;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- Log.d(TAG, "starting service");
- mBindBtn = (Button)findViewById(R.id.bindButton);
- mUnbindBtn = (Button)findViewById(R.id.stopButton);
- mBindBtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- startService(new Intent(LocaleServiceActivity.this, BackgroundService.class));
- }
- });
- mUnbindBtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- stopService(new Intent(LocaleServiceActivity.this, BackgroundService.class));
- }
- });
- }
- }
如果你还是觉得我写的不够详细
看的不够爽 不要紧我把本地Service源代码的下载地址贴出来 欢迎大家一起讨论学习ALFA DeV工作室希望可以和大家一起进步。
下载地址:http://download.csdn.net/source/3568186
秘籍四、理解远程Service
1、首先需要定义AIDL文件
定义好AIDL文件之后,eclipse会在gen目录下面自动生成IStockQuoteService.java文件。在这个接口当中定义了一个静态抽象类Stub,这个类继承了android.os.Binder并且实现了IStockQuoteService接口。
2、实现远程Service
- public class StockQuoteService extends Service {
- private static final String TAG = "StockQuoteService";
- public class StockQuoteServiceImpl extends IStockQuoteService.Stub{
- @Override
- public double getQuote(String ticker) throws RemoteException {
- Log.v(TAG, "getQuote() called for" + ticker);
- return 20.0;
- }
- }
- @Override
- public void onCreate() {
- Log.v(TAG,"onCreate() called");
- super.onCreate();
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- Log.v(TAG,"onStartCommand() called");
- return super.onStartCommand(intent, flags, startId);
- }
- @Override
- public IBinder onBind(Intent intent) {
- return new StockQuoteServiceImpl();
- }
- @Override
- public void onDestroy() {
- Log.v(TAG,"onDestory() called");
- super.onDestroy();
- }
- }
为了将此Service暴露给其他客户端,我们需要在项目清单文件中加上如下配置:
- <service android:name="StockQuoteService">
- <intent-filter>
- <action android:name="com.freedie.remoteservicedemo.IStockQuoteService"/>
- </intent-filter>
- </service>
3、客户端对远程Service进行调用
需要将aidl文件copy到客户端应用程序当中,当然你需要建立好原先AIDL所在的包名,然后将AIDL文件放在此包名下。
- public class MainActivity extends Activity {
- private static final String TAG = "MainActivty";
- private Button bindBtn, calBtn, unbindBtn;
- private IStockQuoteService stockService = null;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- bindBtn = (Button)findViewById(R.id.bindButton);
- calBtn = (Button)findViewById(R.id.calButton);
- unbindBtn = (Button)findViewById(R.id.unbindButton);
- bindBtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- bindService(new Intent(IStockQuoteService.class.getName()), serConn, Context.BIND_AUTO_CREATE);
- }
- });
- calBtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- calService();
- }
- });
- unbindBtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- unbindService(serConn);
- }
- });
- }
- private void calService() {
- try{
- double val = stockService.getQuote("ALFA DeV");
- Toast.makeText(this, "Value From service is:" + val, Toast.LENGTH_SHORT).show();
- }catch(RemoteException e){
- Log.e(TAG, e.getMessage());
- }
- }
- private ServiceConnection serConn = new ServiceConnection(){
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- Log.v(TAG, "onServiceConnected() callled");
- stockService = IStockQuoteService.Stub.asInterface(service);
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- Log.v(TAG, "onServiceDisconnected() called");
- stockService = null;
- }
- };
- }
客户端也写好之后,需要写将远程Service应用程序部署到真机或者模拟器上面,然后将客户端调用程序也部署上去。
单击Bind按钮之后,进行绑定远程Service。单击Cal按钮,界面效果如下:
调用远程服务成功。
本篇博客简单介绍了两种不同的Service,本地服务如何定义,以及客户端如何进行调用,以及远程服务的定义和调用方法。下篇博客,ALFA DeV工作室将会为大家更深入的讲解如何使用Service,在什么情况下使用Service,目的是让大家对Service有个非常清晰地认识,能够在适当场合正确使用Service。
最后如果你还是觉得我写的不够详细
看的不够爽 不要紧我把远程服务源代码的下载地址贴出来 欢迎大家一起讨论学习ALFA DeV工作室希望可以和大家一起进步。