Android的几种通讯方式

Android 进程间的通信

在 Android 世界里,默认的每个 APP 是一个单独的进程。其实这样的描述是不严格的,因为咱们要研究 Android 的进程间通信,肯定出了和其他的 APP 通信外,还可能和同一个 APP 下的其他进程通信。在 Java 里,每一个虚拟机是一个进程,Android 也是虚拟机的机制,你每启动一个 APP,默认会启动一个虚拟机上,一个虚拟机就是一个进程。在 APP 里,有还被运行创建另外的进程,在主进程结束后,这个进程还可以独立运行。

咱们这里不讨论怎么创建进程,咱们先讨论怎么让进程通信。
Android 里有四个基础组件,Activity,Service,Broastcast,Content Provider。

Activity
Activity 跨进程通信其实咱们很经常用,但是却忽略了。咱们通过实例化一个 Intent,然后 startActivity ,是不是把一个意图,也就是 Intent 发送出去了?那么最终被 start 的 Activity 完全可能是在另外一个进程里的啊。比如你发送微博,你在你的 APP 里,通过 Intent 把数据发送给了微博客户端,微博客户端发完微博又回到了你的 APP,这个时候你需要 startActivityForResult 和 onActivityResult 就解决了你的进程和微博客户端进程的通信。

Service
Service 是最复杂的。一般情况下,Service 和应用同在一个进程下,并且是主线程的。所以,一般 Service 也叫本地Service。既然有本地的,就有外地的,叫做远程 Service,remote service。如果一个 Service 是 remote service 的话,那么这个 Service 就会运行在一个独立的进程里。

既然跨进程了,就需要了解一个东西,叫 AIDL , Android Interface Definition Language。它是一个定义语言,说白了,你可以理解它是一个中间的桥梁,进程A得知道进程B的接口(也就是方法),才可以调用,传递参数,获取返回值。
Content Provider
Android 里,使用SQLite 数据库来存储数据,一般使用 SQLiteOpenHelper 创建的数据库是私有的,不希望它被其他的应用程序读取,甚至写入的,这个机制能保护你应用的数据安全。但是有时候你又需要对外提供数据,如果说电话本,短信等等,其他的应用都可以获取到的。Content Provider 其实也是对 SQLite 的另外一种封装而已,它提供了另外一种数据的访问方式。这个时候,你就需要理解什么是 URI ,统一资源路径。URI 就相当于官话,你懂我懂大家懂,而私有数据库就相当于方言,别人一般听不懂,hacker 例外。

Content Provider 可以在不同的应用之间共享数据。
Broadcast
广播也很好理解了,系统广播一句“狼来啦”,然后大家都知道手机快没电了。A 广播一个消息(其实也是一个Intent),然后其他的应用程序可以接收到这个广播(当然得注册监听这个广播)。

广播虽然好用,但是有些局限性,通过 Intent 来携带数据,一般不允许携带复杂的数据,特别是一些大对象。另外,广播的频率也是一个问题,小喇叭嘴太欠的话,会遭人恨的。

Bound Services
先来一段官方的解释:A bound service is the server in a client-server interface. A bound service allows components (such as activities) to bind to the service, send requests, receive responses, and even perform interprocess communication (IPC).

一个 Bound Service 可以和其他组件(当然也包括 Service 本身了)进行交互,也包括咱们要说的跨进程通信了。

一说到 Android 的跨进程通信,大家都想到了 AIDL,其实不仅是 AIDL,包括咱们上面说的,可以通过 Intent 的发送,来进行跨进程的通信,除此之外,用 bindService 的方式,也不仅仅是 AIDL。

从创建 Bound Service 开始。一般咱们使用 bindService 来获取一个 iBinder 对象,然后通过 iBinder 对象来与 Service 进行通信。
Extending the Binder class
最一般的方式,就是继承于 Binder(Binder implements IBinder),然后写你想要的方法,在 Service 的 onBind 的方法里返回一个 Binder 对象。在其他组件里(比如 Activity)通过 bindService 来获取这个 Binder 对象,然后就可以和 Service 进行交互了。

这种方式适用于调用 Service 的组件和 Service 在同一个进程里。也就是没有跨进程啥事。

官方文档有这么一句话:The only reason you would not create your interface this way is because your service is used by other applications or across separate processes.也就是说,除非你真的需要跨进程,不然这个方式已经够用了,不要瞎搞跨进程。

Using a Messenger
messenger 的翻译是报信者,送信者,信使。

这种方式,需要你在 Service 里实现一个 Handler 的子类,跟普通的 Handler 一样一样的。然后还需要一个 Messenger 对象,在 onBind 方法,通过 Messenger.getBinder() 获取一个 Binder。

Activity 通过 bindService 获取到 Binder 后,new Messenger(binder) ,Messenger 有个 send 方法,可以把一个 Message 对象发送出去,Service 的 Handler 就会收到这个 Message。跟咱们平常使用的 Handler 和 Message 的方式基本一样,只不过它是跨进程的。

不过到目前为止,这个通信是单向的,由 Activity 向 Service 发送,如果 Service 执行完某些操作后,需要给个响应呢,这个时候,需要 Activity 也实现一个 Messenger ,然后在 send() 的时候需要把这个 Messenger 也传过去。这样在 Service 执行完任务后,也会发送一个 Message 给 Activity。这样就实现了双方的通信。
这个消息队列是在一个线程里去管理的,所以你的 Service 是线程安全的,你不需要额外的设计来保证线程安全。

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.

AIDL
下面就开始 AIDL 了,这是大家很期待的,但是又是 Android 官方特别不推荐的方式。

AIDL (Android Interface Definition Language) performs all the work to decompose objects into primitives that the operating system can understand and marshall them across processes to perform IPC. The previous technique, using a Messenger, is actually based on AIDL as its underlying structure. As mentioned above, the Messenger creates a queue of all the client requests in a single thread, so the service receives requests one at a time. If, however, you want your service to handle multiple requests simultaneously, then you can use AIDL directly. In this case, your service must be capable of multi-threading and be built thread-safe.

看粗体的字。然后再看这段话下面还有一段话:

Note: Most applications should not use AIDL to create a bound service, because it may require multithreading capabilities and can result in a more complicated implementation. As such, AIDL is not suitable for most applications and this document does not discuss how to use it for your service. If you’re certain that you need to use AIDL directly, see the AIDL document.
这段话的粗体不是我整的,是文档上的。意思就是说大部分应用不需要 AIDL 的。主要的问题出在,如果你使用 AIDL,你必须处理好多线程,并且保证线程安全。

这里不具体描述怎么使用 AIDL,大概就是需要写一个 aidl 文件,然后显示一个 Stub 的子类,其实 Stub 是 extends Binder,然后在 Service 的 onBind() 方法里返回一个 Stub 对象。其他组件还是通过 bindService 的方式获取这个 Binder,并且可以直接调用。

转载自:http://www.binkery.com/

Android进程通信(Inter-process Communication, IPC)是指在不同进程之间进行数据交互和通信的方法。Android提供了多种方式实现进程通信,以下是常用的几种方式: 1. Binder机制:Binder是一种进程通信技术,它基于Linux内核提供的Binder驱动。通过Binder,我们可以将一个Service注册为Binder服务,其他进程可以通过Binder进行远程调用,实现进程间的通信。 2. 文件共享:进程可以通过共享文件的方式实现通信。一个进程将数据写入文件,其他进程读取该文件数据,从而实现进程间的信息传递。 3. Socket通信:可以使用Socket套接字进行进程通信。一个进程作为服务器,另一个进程作为客户端,通过Socket建立连接进行数据交互。 4. ContentProvider:ContentProvider是Android中用于实现进程间共享数据的一种组件。通过ContentProvider,一个进程可以提供数据给其他进程进行读写操作。 5. BroadcastReceiver:广播是一种常见的进程通信方式。一个进程发送广播消息,其他进程通过注册相应的广播接收器来接收并处理广播消息。 6. Messenger:Messenger是一种轻量级的进程通信方式。通过Messenger,一个进程可以发送消息给另一个进程,实现进程间的通信。 以上是常用的几种Android进程通信方式,开发者可以根据具体需求选择合适的方式来实现进程通信
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值