现在的位置: 首页 > 综合 > 正文

android Service详解

2013年10月11日 ⁄ 综合 ⁄ 共 8420字 ⁄ 字号 评论关闭

转载自博客原文地址: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

  1. public class TestService1 extends Service {  
  2.     private static final String TAG = "TestService1";  
  3.       
  4.     @Override  
  5.     public void onCreate() {  
  6.         Log.d(TAG, "-->onCreate() method was invoked");  
  7.         super.onCreate();  
  8.     }  
  9.       
  10.     @Override  
  11.     public IBinder onBind(Intent intent) {  
  12.         Log.d(TAG, "-->onBind() method was invoked");  
  13.         return null;  
  14.     }  
  15.   
  16. }  

首先,定义的Service需要继承android.app.Service,然后需要在项目清单文件当中声明此Service。

  1. <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 

  1. public class BackgroundService extends Service {  
  2.     private NotificationManager notificationMgr;  
  3.       
  4.     @Override  
  5.     public void onCreate() {  
  6.         super.onCreate();  
  7.         notificationMgr = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);  
  8.         displayNotificationMessage("starting Background Services");  
  9.         Thread tr = new Thread(new ServiceWorker());  
  10.         tr.start();  
  11.     }  
  12.       
  13.     class ServiceWorker implements Runnable{  
  14.          @Override  
  15.         public void run() {  
  16.              //do background processing here  
  17.              //stop when service when done   
  18.              //BackgroundService.this.stopSelf();  
  19.         }  
  20.     }  
  21.     private void displayNotificationMessage(String message) {  
  22.         Notification notification = new Notification(R.drawable.icon, message, System.currentTimeMillis());  
  23.         PendingIntent contentIntent = PendingIntent.getActivity(this0new Intent(this, MainActivity.class), 0);  
  24.         notification.setLatestEventInfo(this"Background Service", message, contentIntent);  
  25.         notificationMgr.notify(R.id.app_notification_id, notification);  
  26.     }  
  27.       
  28.     @Override  
  29.     public IBinder onBind(Intent intent) {  
  30.         return null;  
  31.     }  
  32.       
  33.     @Override  
  34.     public void onDestroy() {  
  35.         super.onDestroy();  
  36.         displayNotificationMessage("stopping Background Service");  
  37.     }  
  38. }  

客户端如何调用本地Service:

  1. public class LocaleServiceActivity extends Activity {  
  2.     private static final String TAG = "LocaleServiceActivity";  
  3.       
  4.     Button mBindBtn, mUnbindBtn;  
  5.     @Override  
  6.     public void onCreate(Bundle savedInstanceState) {  
  7.         super.onCreate(savedInstanceState);  
  8.         setContentView(R.layout.main);  
  9.           
  10.         Log.d(TAG, "starting service");  
  11.         mBindBtn = (Button)findViewById(R.id.bindButton);  
  12.         mUnbindBtn = (Button)findViewById(R.id.stopButton);  
  13.           
  14.         mBindBtn.setOnClickListener(new OnClickListener() {  
  15.             @Override  
  16.             public void onClick(View v) {  
  17.                 startService(new Intent(LocaleServiceActivity.this, BackgroundService.class));  
  18.             }  
  19.         });  
  20.           
  21.         mUnbindBtn.setOnClickListener(new OnClickListener() {  
  22.               
  23.             @Override  
  24.             public void onClick(View v) {  
  25.                 stopService(new Intent(LocaleServiceActivity.this, BackgroundService.class));  
  26.             }  
  27.         });  
  28.     }  
  29. }  

如果你还是觉得我写的不够详细
看的不够爽 不要紧我把本地Service源代码的下载地址贴出来 欢迎大家一起讨论学习ALFA DeV工作室希望可以和大家一起进步。


下载地址:
http://download.csdn.net/source/3568186

秘籍四、理解远程Service

1、首先需要定义AIDL文件

定义好AIDL文件之后,eclipse会在gen目录下面自动生成IStockQuoteService.java文件。在这个接口当中定义了一个静态抽象类Stub,这个类继承了android.os.Binder并且实现了IStockQuoteService接口。


2、实现远程Service

  1. public class StockQuoteService extends Service {  
  2.     private static final String TAG = "StockQuoteService";  
  3.       
  4.     public class StockQuoteServiceImpl extends IStockQuoteService.Stub{  
  5.   
  6.         @Override  
  7.         public double getQuote(String ticker) throws RemoteException {  
  8.             Log.v(TAG, "getQuote() called for" + ticker);  
  9.             return 20.0;  
  10.         }  
  11.           
  12.     }  
  13.       
  14.     @Override  
  15.     public void onCreate() {  
  16.         Log.v(TAG,"onCreate() called");  
  17.         super.onCreate();  
  18.     }  
  19.     @Override  
  20.     public int onStartCommand(Intent intent, int flags, int startId) {  
  21.         Log.v(TAG,"onStartCommand() called");  
  22.         return super.onStartCommand(intent, flags, startId);  
  23.     }  
  24.       
  25.     @Override  
  26.     public IBinder onBind(Intent intent) {  
  27.         return new StockQuoteServiceImpl();  
  28.     }  
  29.       
  30.     @Override  
  31.     public void onDestroy() {  
  32.         Log.v(TAG,"onDestory() called");  
  33.         super.onDestroy();  
  34.     }  
  35.   
  36. }  

为了将此Service暴露给其他客户端,我们需要在项目清单文件中加上如下配置:

  1.  <service android:name="StockQuoteService">  
  2.     <intent-filter>  
  3.         <action android:name="com.freedie.remoteservicedemo.IStockQuoteService"/>  
  4.     </intent-filter>  
  5. </service>  

3、客户端对远程Service进行调用

需要将aidl文件copy到客户端应用程序当中,当然你需要建立好原先AIDL所在的包名,然后将AIDL文件放在此包名下。

  1. public class MainActivity extends Activity {  
  2.     private static final String TAG = "MainActivty";  
  3.       
  4.     private Button bindBtn, calBtn, unbindBtn;  
  5.       
  6.     private IStockQuoteService stockService = null;  
  7.       
  8.     @Override  
  9.     public void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         setContentView(R.layout.main);  
  12.           
  13.         bindBtn = (Button)findViewById(R.id.bindButton);  
  14.         calBtn = (Button)findViewById(R.id.calButton);  
  15.         unbindBtn = (Button)findViewById(R.id.unbindButton);  
  16.           
  17.           
  18.           
  19.         bindBtn.setOnClickListener(new OnClickListener() {  
  20.               
  21.             @Override  
  22.             public void onClick(View v) {  
  23.                 bindService(new Intent(IStockQuoteService.class.getName()), serConn, Context.BIND_AUTO_CREATE);  
  24.             }  
  25.         });  
  26.           
  27.         calBtn.setOnClickListener(new OnClickListener() {  
  28.               
  29.             @Override  
  30.             public void onClick(View v) {  
  31.                 calService();  
  32.             }  
  33.         });  
  34.           
  35.         unbindBtn.setOnClickListener(new OnClickListener() {  
  36.               
  37.             @Override  
  38.             public void onClick(View v) {  
  39.                 unbindService(serConn);  
  40.             }  
  41.         });  
  42.     }  
  43.       
  44.     private void calService() {  
  45.         try{  
  46.             double val = stockService.getQuote("ALFA DeV");  
  47.             Toast.makeText(this"Value From service is:" + val, Toast.LENGTH_SHORT).show();  
  48.         }catch(RemoteException e){  
  49.             Log.e(TAG, e.getMessage());  
  50.         }  
  51.     }  
  52.   
  53.     private ServiceConnection serConn = new ServiceConnection(){  
  54.   
  55.         @Override  
  56.         public void onServiceConnected(ComponentName name, IBinder service) {  
  57.             Log.v(TAG, "onServiceConnected() callled");  
  58.             stockService = IStockQuoteService.Stub.asInterface(service);  
  59.         }  
  60.   
  61.         @Override  
  62.         public void onServiceDisconnected(ComponentName name) {  
  63.             Log.v(TAG, "onServiceDisconnected() called");  
  64.             stockService = null;  
  65.         }  
  66.           
  67.     };  
  68. }  

客户端也写好之后,需要写将远程Service应用程序部署到真机或者模拟器上面,然后将客户端调用程序也部署上去。
单击Bind按钮之后,进行绑定远程Service。单击Cal按钮,界面效果如下:


调用远程服务成功。

本篇博客简单介绍了两种不同的Service,本地服务如何定义,以及客户端如何进行调用,以及远程服务的定义和调用方法。下篇博客,ALFA DeV工作室将会为大家更深入的讲解如何使用Service,在什么情况下使用Service,目的是让大家对Service有个非常清晰地认识,能够在适当场合正确使用Service。


最后如果你还是觉得我写的不够详细
看的不够爽 不要紧我把远程服务源代码的下载地址贴出来 欢迎大家一起讨论学习ALFA DeV工作室希望可以和大家一起进步。

抱歉!评论已关闭.