首先要明白需要的情景,然后对三种方式进行选择:

(一)可以接收Service的信息(获取Service中的方法),但不可以给Service发送信息

(二) 使用Messenger既可以接受Service消息,也可以发送Service消息。但是无法调用Service中的方法。因为利用Message,所以不用担心并发

Extending the Binder classIf your service is private to your own application and runs in the same process as the client (which is common), you should create your interface by extending the Binder class and returning an instance of it from onBind(). The client receives the Binder and can use it to directly access public methods available in either the Binder implementation(得到Service对象,从而获取Service中的方法) or even the Service.This is the preferred technique when your service is merely a background worker for your own application. The only reason you would not create your interface this way is because your service is used by other applications or across separate processes.Service代码如下:
Activity代码如下:Using a Messenger
If you need your interface to work across different processes, you can create an interface for the service with a Messenger. In this manner, the service defines a Handler that responds to different types of Message objects. This Handler is the basis for a Messenger that can then share an IBinder with the client, allowing the client to send commands to the service using Message objects. Additionally, the client can define a Messenger of its own so the service can send messages back.

This is the simplest way to perform interprocess communication (IPC), because the Messenger queues all requests into a single thread so that you don't have to design your service to be thread-safe.

If you need your service to communicate with remote processes, then you can use a Messenger to provide the interface for your service. This technique allows you to perform interprocess communication (IPC) without the need to use AIDL.

Here's a summary of how to use a Messenger:

  • The service implements a Handler that receives a callback for each call from a client.
  • The Handler is used to create a Messenger object (which is a reference to the Handler).
  • The Messenger creates an IBinder that the service returns to clients from onBind().
  • Clients use the IBinder to instantiate the Messenger (that references the service's Handler), which the client uses to sendMessage objects to the service.
  • The service receives each Message in its Handler—specifically, in the handleMessage() method.

    In this way, there are no methods for the client to call on the service. Instead, the client delivers messages (Message objects) that the service receives in its Handler.

    Messenger和AIDL的比较:

    Compared to AIDL

    When you need to perform IPC, using a Messenger for your interface is simpler than implementing it with AIDL, because Messenger queues all calls to the service, whereas, a pure AIDL interface sends simultaneous requests to the service, which must then handle multi-threading.

    For most applications, the service doesn't need to perform multi-threading, so using a Messengerallows the service to handle one call at a time. If it's important that your service be multi-threaded, then you should use AIDL to define your interface.

    Binding to a Service

    Application components (clients) can bind to a service by calling bindService(). The Android system then calls the service's onBind() method, which returns an IBinder for interacting with the service.

    The binding is asynchronous. bindService() returns immediately and does not return the IBinder to the client. To receive the IBinder, the client must create an instance of ServiceConnection and pass it to bindService(). The ServiceConnection includes a callback method that the system calls to deliver the IBinder.

    Managing the Lifecycle of a Bound Service


    When a service is unbound from all clients, the Android system destroys it (unless it was also started with onStartCommand()). As such, you don't have to manage the lifecycle of your service if it's purely a bound service—the Android system manages it for you based on whether it is bound to any clients.

    However, if you choose to implement the onStartCommand() callback method, then you must explicitly stop the service, because the service is now considered to be started. In this case, the service runs until the service stops itself with stopSelf() or another component calls stopService(), regardless of whether it is bound to any clients.

    Additionally, if your service is started and accepts binding, then when the system calls your onUnbind()method, you can optionally return true if you would like to receive a call to onRebind() the next time a client binds to the service (instead of receiving a call to onBind()). onRebind() returns void, but the client still receives the IBinder in its onServiceConnected() callback. Below, figure 1 illustrates the logic for this kind of lifecycle.

    (三) 使用AIDL (1.不需要IPC:implement a Binder; 2.需要IPC,不需要并发:use a Messenger; 3.需要IPC,需要并发:AIDL) Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service. If you do not need to perform concurrent IPC across different applications, you should create your interface by implementing a Binder or, if you want to perform IPC, but do not need to handle multithreading, implement your interface using a Messenger.

    1. Create the .aidl file

      This file defines the programming interface with method signatures.

    2. Implement the interface

      The Android SDK tools generate an interface in the Java programming language, based on your .aidl file. This interface has an inner abstract class named Stub that extends Binder and implements methods from your AIDL interface. You must extend the Stub class and implement the methods.

    3. Expose the interface to clients

      Implement a Service and override onBind() to return your implementation of the Stub class.

      IRemoteService.aidl文件:

      // IRemoteService.aidl
      package com.example.boundservice;// Declare any non-default types here with import statements/** Example service interface */
      interface IRemoteService {/** Request the process ID of this service, to do evil things with it. */int getPid();/** Demonstrates some basic types that you can use as parameters* and return values in AIDL.*/void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,double aDouble, String aString);
      }

      自动生成(eclipse自动,studio需要rebuild)的IRemoteService.java:

转载于:https://www.cnblogs.com/qiangxia/p/4992443.html

[转] Bound Service的三种方式(Binder、 Messenger、 AIDL)相关推荐

  1. 为 Angular service 注册 provider 的三种方式

    对于要用到的任何服务(service),你必须至少注册一个提供者(provider).服务可以在自己的元数据中把自己注册为提供者,这样可以让自己随处可用.或者,你也可以为特定的模块或组件注册提供者. ...

  2. vue 函数 路由跳转_vue中通过路由跳转的三种方式

    router-view 实现路由内容的地方,引入组件时写到需要引入的地方 需要注意的是,使用vue-router控制路由则必须router-view作为容器. 通过路由跳转的三种方式 1.router ...

  3. linux+Qt 下利用D-Bus进行进程间高效通信的三种方式

    linux+Qt 下利用D-Bus进行进程间高效通信的三种方式 原文链接: https://www.cnblogs.com/wwang/archive/2010/10/27/1862552.html ...

  4. SpringBoot静态获取 bean的三种方式,你学会了吗?

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/showchi/article/details/97005720 注意:调用者要被spring管理 ...

  5. Workflow 4.0 中三种方式实现workflow的触发调用

    1:使用WorkflowInvoker类中的InVoke静态方法-->WorkflowInvoker.Invoke(myWF); //myWF为自定义的workflow实例 [这种方式可以像一个 ...

  6. Linux中设置服务自启动的三种方式

    有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统服务 主要用三种方式进行这一操作: ln -s                       在/etc/rc.d/rc*.d目录中建立/e ...

  7. Linux中设置服务自启动的三种方式(转)

    有时候我们需要Linux系统在开机的时候自动加载某些脚本或系统服务 主要用三种方式进行这一操作: ln -s                       在/etc/rc.d/rc*.d目录中建立/e ...

  8. 在Linux安装配置Tomcat 并部署web应用 ( 三种方式 )

    系统版本:centos6.5版本 java版本:1.7 一.准备工作 1.java -version 检查是否有java环境,没有则需要去安装并配置到环境变量中. 2.下载tomcat包,下载地址:h ...

  9. 三种方式实现观察者模式 及 Spring中的事件编程模型

    观察者模式可以说是众多设计模式中,最容易理解的设计模式之一了,观察者模式在Spring中也随处可见,面试的时候,面试官可能会问,嘿,你既然读过Spring源码,那你说说Spring中运用的设计模式吧, ...

最新文章

  1. 不吹不黑!让你搜遍GitHub都找不到这么吊炸天的网约车项目!
  2. Interview:算法岗位面试—11.05下午上海某银行信息(总行,四大行之一)技术岗笔试记录
  3. mint ui tabbar选中后怎么改变icon图标_UI全书(下)读后梳理:iPhone设计规范和Material Design规范...
  4. Python实训day03pm【列表生成式、非文本文件的读写与复制、文本文件读写练习】
  5. HDU Problem - 2732 Leapin' Lizards(最大流,拆点建边)
  6. 【题解】洛谷P1541 [NOIP2010TG] 乌龟棋(类似背包的DP)
  7. 同意按钮,倒计时10秒,同意按钮变为可提交的
  8. C语言 文件读写 fputc 函数 - C语言零基础入门教程
  9. vs.net各版本解决方案相互转换工具
  10. 傅里叶级数的数学推导
  11. python网络爬虫爬取视频_Python网络爬虫——爬取小视频网站源视频!自己偷偷看哦!...
  12. 如何使用Movavi Academic制作出实用的互动视频
  13. H750/H755 安装centos系统
  14. cad 打开硬件加速卡_如何让CAD运行速度加快?
  15. java正则表达式控制半角字符串输入
  16. 深圳市自助图书馆详细分布地址
  17. 前端设置画布的高度_前端页面内的高度、位置简述
  18. 求一个整数的各个位数
  19. 万字长文读透 Redis
  20. Linux必学的60个命令(文字整理版)

热门文章

  1. Python升级pip并安装opencv、moviepy包
  2. android nsdservice 类型,Android NSD onServiceFound()没有被调用
  3. 化工计算机软件基础考试题,化工原理模拟试题(一)及答案.doc
  4. access字段类型varchar_数据库即将被淘汰的几种数据类型,烦恼还是解脱?
  5. python同时发大量请求_Python批量发送post请求的实现代码
  6. editplus 快捷键及设置tab空白符及删除空格空行
  7. 修改system.img的大小限制
  8. SpringBoot实战(五):配置健康检查与监控
  9. 从AI打王者荣耀到自动驾驶,高通一口气公布了5G+AI未来的无数种可能
  10. 硬骨难啃:大众想收购自动驾驶公司Aurora,但被拒绝了