`
wb284551926
  • 浏览: 539695 次
文章分类
社区版块
存档分类
最新评论

Android Service 之Bound Service(转载)

 
阅读更多

 前面提了start service 是可以独立与调用程序运行的(见http://www.linuxidc.com/Linux/2011-09/42254.htm),也就是说启动它的程序消亡了,该service还是可以继续运行的。

    这里的Bound Service 就没这好事了,它仅仅服务于调用它的组件,不能脱离于调用它的组件而生存。人都完蛋了,人体的一些器官有啥用呢。。。

    Bound Service 是允许其他的组件(如 Activities)绑定到其上面,可以发送请求,也可以接受请求,甚至可以进行进程间的通信。

   那么如何来创建一个Bound Service 呢?当创建一个能提供绑定功能的服务时,我们就必须要提供一个IBinder对象,客户端就可以使用IBinder对象来与服务进行交互,在Android系统中,有三种方式可以创建IBinder:

 1.扩展Binder类:这种方式当你的service只给当前的程序用而且在后台执行的时候采用这种方式比较好。意思很简单,不需要跨进程间通信。

  2.使用Message机制:消息机制相对于Binder的方式就比较复杂点,它支持跨进程间调用的(这种方式的基础其实也是AIDL,只不过不需要涉及到AIDL那么深),这种情况下,service会定义一个handle来出来不同的object的服务请求,有一点要提起的是,这里的IBinder对所有的客户端来说是共享的。当然我们的客户端也可以定义自己的handle来处理和service之间来进行交互。消息机制是一种实现进程间通信的最简单的方式,因为所有的请求都会放到一个消息队列当中去进行轮询处理(意思就是单线程啦),每次只处理一个服务请求,这样就不要保证你设计的service需要保证是线程安全状态的。

  3.使用AIDL(Android interface definition language 安卓接口定义语言)。:这种方式是最难的一种方式了,他会把所有的工作都会分解成最原始的语义,从而使得系统能够理解该工作目的。然后进行进程间的通信。前面说过message采用的是AIDL的架构基础的,当我们需要同时处理多个请求,而不是放在队列里面一个一个的处理的时候就可以采用这种方式了。使用这种方式你必须保证的你的service能够支持多线程并且保证其实线程安全状态。一般情况下会先创建一个.aldl文件来定义程序的接口,系统会为你自动自动生成抽象类以及IPC的处理,然后你就可以在你的service种进行extend了。

 本文此处介绍Binder类,后续的Message 和AIDL机制会慢慢更新上来。

如何创建一个bound service呢?
要素:
必须得实现onBind()函数,然后返回一个IBinder的接口,IBinder定义了与service通信的接口;
其它应用程序通过调用bindService()来绑定到该service上并获取接口以及调用service的方法。

service生存的唯一理由是为了绑定它的应用程序服务,因此,应用程序如果消失了,它也失去了它生存的意义了。好伟大的“爱情”,现实当中我们找不到这样的爱情,代码中找到了,HOHO。
好了,我们来梳理下创建一个bound service的过程:
首先,我们必须得定义一个客户端如何与service通信的接口,该接口必须是实现了IBinder的接口,该接口是从obBind()函数的回调方法中返回来的。一旦客户端收到了IBinder接口,就可以和service间进行通信了。

多个客户端可以和service绑定一次,当客户端与service交互结束之后,将会调用unbindService()来解除绑定,一旦整个系统中没有客户端与service进行绑定了,那么系统将会destory该service。

上个具体的例子并附注说明:

例子实现一个service来项客户端提供一个随机产生的数字功能。客户端将service提供的随机数显示在自己的界面上。

1.LocalService.java类,继承自service,代码以及注释如下:

  1. package com.android.localboundservice;  
  2.   
  3. import java.util.Random;  
  4.   
  5. import android.app.Service;  
  6. import android.content.Intent;  
  7. import android.os.Binder;  
  8. import android.os.IBinder;  
  9. import android.util.Log;  
  10.   
  11. /** 
  12.  *  
  13.  * @author bluesky 
  14.  * 创建一个bindservice 的步骤: 
  15.  * 实现一个IBinder接口类,并返回一个IBinder对象,该对象用于传递给客户端来进行调用service的服务。通常的做法是extends Binder类, 
  16.  * 应为该类实现了IBinder的接口。然后从onBind函数中返回当前service的一个实例,该实例是IBinder类型。 
  17.  * 实现service中需要提供给客户端的服务即可。 
  18.  * 至于客户端如何使用service请看客户端的操作。 
  19.  */  
  20.   
  21. public class LocalService extends Service {  
  22.   
  23.     public IBinder localBinder = new MyLocalService();  
  24.     public Random m_generator = new Random();  
  25.     public static final int num = 2000;  
  26.     private static final String TAG = "LocalService";  
  27.     /** 
  28.      *  
  29.      * @author bluesky 
  30.      * 该类作用: 
  31.      * 1.yLocalService 继承自Binder类,而Binder类是实现了IBinder接口的。该接口用于提供给客户端, 
  32.      * 可以用于客户端获取service的对象,然后调用service端的方法。 
  33.      */  
  34.     public class MyLocalService extends Binder{  
  35.         public LocalService getService(){  
  36.             Log.d(TAG, "********getService");  
  37.             return LocalService.this;  
  38.         }  
  39.     }  
  40.     /** 
  41.      * 由于是采用IBinder形式进行service绑定的,这里在绑定的时候我们要返回一个IBinder对象,该对象用于给客户端使用service的服务。 
  42.      * 该对象就是前面我们创建的MyLocalService的对象,该对象是继承了Binder类,Binder类实现了IBinder接口。 
  43.      */  
  44.     @Override  
  45.     public IBinder onBind(Intent arg0) {  
  46.         // TODO Auto-generated method stub   
  47.         Log.d(TAG, "*******return IBinder interface");  
  48.         return localBinder;  
  49.     }  
  50.       
  51.     /** 
  52.      * @param null; 
  53.      * @return 随机数。 
  54.      * service中提供的方法,用于产生一个随机数。 
  55.      */  
  56.     public int generatorInt(){  
  57.         Log.d(TAG, "******get random generator!");  
  58.         return m_generator.nextInt(num);  
  59.     }  
  60.   
  61. }  

2 LocalBoundServiceActivity.java继承自Activity作为我们的客户端: 

 
  1. package com.android.huawei.localboundservice;  
  2.   
  3. import com.android.localboundservice.LocalService.MyLocalService;  
  4.   
  5. import android.app.Activity;  
  6. import android.os.Bundle;  
  7. import android.os.IBinder;  
  8. import android.widget.Button;  
  9. import android.widget.Toast;  
  10. import android.util.Log;  
  11. import android.view.*;  
  12. import android.content.ComponentName;  
  13. import android.content.Context;  
  14. import android.content.Intent;  
  15. import android.content.ServiceConnection;  
  16.   
  17. /** 
  18.  *  
  19.  * @author bluesky 
  20.  * 客户端如何使用binder service 
  21.  * 1.在Activity的start的时候使用intent对象启动bindService(Intent intent,ServiceConnection conn,int flags)来进行绑定。 
  22.  * bindService的需要传递三个参数: 
  23.  * 1 绑定service的intent; 
  24.  * 2 ServiceConnection的接口变量,既然是接口,那么我们肯定需要在程序中去实现了。这个变量主要是当service连接和断开的时候传递相关的信息。需要实现两个回调函数 
  25.  * 1)onServiceConnected():当连接建立起来的时候,传递由onBind函数中返回的IBinder的接口对象。 
  26.  * 2)onServiceDisConnected():当连接异常断开的时候,系统会走到该函数处,比如说service被杀死,或者程序异常崩溃。但是必须记住:客户端调用unbindService()函数的时候 
  27.  * 是不会走到该函数处的。调用客户端消亡的时候,service跟着消亡。 
  28.  * 3:标记,这里的标记我们选择BIND_AUTO_CREATE表述当bind存在的时候自动创建service。 
  29.  *  
  30.  */  
  31. public class LocalBoundServiceActivity extends Activity {  
  32.   
  33.     private static final String TAG = "LocalBoundServiceActivity";  
  34.     private Button mBtnService = null;  
  35.     private boolean isConn = false//该标记位主要用于判断当前是连接状态呢还是断开状态   
  36.     private LocalService recSer = null;//定义一个LocalService变量,该变量继承自Binder类(实现了IBinder接口)   
  37.     /** Called when the activity is first created. */  
  38.     @Override  
  39.     public void onCreate(Bundle savedInstanceState) {  
  40.         super.onCreate(savedInstanceState);  
  41.         setContentView(R.layout.main);  
  42.         mBtnService = (Button)findViewById(R.id.bindService);  
  43.           
  44.         /** 
  45.          * 该按钮响应函数用于调用service中的随机数生成器。 
  46.          */  
  47.         mBtnService.setOnClickListener(new Button.OnClickListener(){  
  48.               
  49.             public void onClick(View v){  
  50.                 if(isConn == true){  
  51.                     int num = recSer.generatorInt();  
  52.                     Toast.makeText(LocalBoundServiceActivity.this"生成数为:"+ num, Toast.LENGTH_LONG).show();  
  53.                 }  
  54.             }  
  55.         });  
  56.     }  
  57.     @Override  
  58.     protected void onStart() {  
  59.         // TODO Auto-generated method stub   
  60.         super.onStart();  
  61.         Intent intent = new Intent(LocalBoundServiceActivity.this,LocalService.class);  
  62.         bindService(intent,mcoon,Context.BIND_AUTO_CREATE);//绑定服务   
  63.     }  
  64.     @Override  
  65.     protected void onStop() {  
  66.         // TODO Auto-generated method stub   
  67.         super.onStop();  
  68.         if(isConn){  
  69.             unbindService(mcoon);  
  70.             isConn = true;  
  71.         }  
  72.     }  
  73.     private ServiceConnection mcoon = new ServiceConnection() {  
  74.           
  75.         @Override  
  76.         public void onServiceDisconnected(ComponentName name) {  
  77.             // TODO Auto-generated method stub   
  78.             isConn = false;  
  79.             Log.d(TAG, "service disconnected!!!");  
  80.               
  81.         }  
  82.           
  83.         @Override  
  84.         public void onServiceConnected(ComponentName name, IBinder service) {  
  85.             // TODO Auto-generated method stub   
  86.               
  87.                 MyLocalService bindSer = (MyLocalService)service;  
  88.                 recSer = bindSer.getService();  
  89.                 isConn = true;  
  90.               
  91.             Log.d(TAG, "service connected!!!");  
  92.               
  93.         }  
  94.     };  
  95.       
  96. }  

最后不要忘记在你的manifest文件中加上service的注册:LocalBoundService Manifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="com.android.huawei.localboundservice"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.     <uses-sdk android:minSdkVersion="8" />  
  7.   
  8.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  9.         <activity android:name=".LocalBoundServiceActivity"  
  10.                   android:label="@string/app_name">  
  11.             <intent-filter>  
  12.                 <action android:name="android.intent.action.MAIN" />  
  13.                 <category android:name="android.intent.category.LAUNCHER" />  
  14.             </intent-filter>  
  15.         </activity>  
  16.         <service android:name=".LocalService">  
  17.         </service>  
  18.     </application>  
  19. </manifest>  

程序运行的界面如下:

 

OK了,结果成功显示出来了。

不知道上面的描述可否说清楚了Bounder service的用法,鄙人其实也查过不少书籍没一本书说的全的,只好自己去查官方文档和参考一些老外的书籍。中文书籍发现是真的没办法看,特别是翻译过来的,很多地方翻译的要么不通顺,要么就是曲解了作者本身的含义。还是推荐大家看英文原版的比较好。

后续会慢慢贴上message和AIDL的service机制,到时候大家一起讨论研究。

文档有不足的地方欢迎大家拍砖,讨论。

 

原文地址:http://www.linuxidc.com/Linux/2011-09/42255.htm

分享到:
评论

相关推荐

    Android Service之bound实现

    Android Service之bound实现

    Android Service简单实例

    关于Android Service的简单实例:属于start service类型,而不是bound service。

    绑定服务BoundService详解之AIDL的使用(自定义属性也包含其中)

    代码比较简单,但是步骤结合博客还是很详细的,可以看我的博客http://blog.csdn.net/superbiglw/article/details/53156177

    浅谈Android中Service的注册方式及使用

    Service通常总是称之为“后台服务”,其中“后台”一词是相对于前台而言的,具体是指其本身的运行并不依赖于用户可视的UI界面,因此,从实际业务需求上来理解,Service的适用场景应该具备以下条件: 1.并不依赖于...

    android的服务

    为了处理这种后台进程,Android引入了Service的概念。Service在Android中是一种长生命周期的组件,它不实现任何用户界面。最常见的例子如:媒体播放器程序,它可以在转到后台运行的时候仍然能保持播放歌曲;或者如...

    kotlin-foregroundService:具有android o通知的前台服务android的Kotlin代码

    具有android o通知的前台服务android的Kotlin代码 MainActivity.kt class MainActivity : AppCompatActivity() { var myService: MyService? = null var isBound = false privateval myConnection = object : ...

    Android Studio 3.2 Development Essentials, Kotlin Edition

    65. Implementing an Android Started Service -A WorkedExample bC. Ancdroidtocalbound Services -A WorkedExample 68. An Android Notificatons Tutorial 69. An Android Direct Reply Notification Tutorial . ...

    Android学习笔记之Service

    Bound 当应用程序组件(如某个活动)通过调用bindService()方法绑定到某个服务时,该服务被称为处于绑定状态。绑定服务提供客户机-服务器接口。这个客户机-服务器接口允许应用程序组件使用IPC与服务交互、发送请求、...

    Asynchronous Android Programming

    Enhance UI performance and responsiveness by sending work to a service running in the background Defer, schedule, and batch work on the Android system without compromising the battery life and user ...

    Android 开发指南(二) 服务绑定

    Android 开发指南(二) 服务绑定 Bound Service

    RabbitMQ for Android

    A connection is set up and the queue is bound to group ids. MainActivity starts a service in background which handles the connection with the server. I'm using `EventBus` to communicate between ...

    Asynchronous Android Programming(PACKT,2ed,2016)

    Next, we will discuss the creation of IntentServices, bound services, and external services, which can run in the background even when the user is not interacting with them. In a more advanced phase,...

    TimedDog:适用于Android应用的超时库

    我已经停止使用WorkManager并迁移到Bound Service 。样本修改您的应用程序类,或者创建一个不存在的应用程序类,并在onCreate()方法中初始化TimedDog 。 class MyApp extends Application { @Override public ...

    Android服务应用ClockService实现闹钟功能

    实验步骤:使用BoundService方式开启服务 1、首先定义布局文件,这里不做过多赘述 3、 定义一个Service服务类,然后在类里面定义一个MyBinder的内部类,用于获取Service对象与Service对象状态。在内部类中必须要...

    lee_location_background

    bound_service 颤振中的绑定服务。 入门 这是Flutter中绑定服务的简单实现。 这基于 。 绑定服务使您可以在Flutter应用程序内部运行后台代码,即使该应用程序使用服务的绑定和解除绑定也可以打开或关闭该应用程序...

    OLA_Play_Music_App:音乐流应用程序

    服务(意向服务,绑定服务) OAuth-(Google登录)(FireBase) 自定义RecyclerView适配器SQLite数据库休息电话(排球,翻新) 图像渲染(滑行) JSON解析(Moshi) 内隐,明确意图Android 6.0运行时权限查看活页夹...

Global site tag (gtag.js) - Google Analytics