如果调用者发起另外一个Android进程,方法在另外一个线程中运行,这个线程在和IBinder对象在一个线程池中,因为一个服务可能有多个客户端请求,不止一个线程池会在同一时间调用IBinder的方法。
这个属性可以组件运行的进程。这个属性可以配置组件在一个独立进程运行,或者多个组件在同一个进程运行。甚至可以多个程序在一个进程中运行-如果这些程序共享一个User ID并给定同样的权限。<application> 节点也包含 process 属性,用来设置程序中所有组件的默认进程。
所有的组件在此进程的Android进程中示例化,系统对这些组件的调用从主线程中分离。并非每个对象都会从主线程中分离。一般来说,响应例如View.onKeyDown()用户操作的方法和通知(后面会在Component Lifecycles谈到)的方法也在主线程中运行。
这就表示,组件被系统调用的时候不应该长时间运行或者阻塞操作(如网络操作或者计算大量数据),因为这样会阻塞进程中的其他组件。可以把这类操作从主线程中分离,后面的Threads, 章节会降到。当更加常用的进程无法获取足够内存,Android可能会关闭不常用的进程。下次启动程序的时候会有一次启动进程。
当决定哪个进程需要被关闭的时候, Android会考虑哪个对用户更加有用。如,Android会倾向于关闭一个长期不显示在界面的进程来支持一个经常显示在界面的进程。是否关闭一个进程决定于组件在进程中的状态,参见后面的章节Component Lifecycles.
即使为组件分配了不同的进程,有时候也需要再分配Android进程。比如用户界面需要很快对用户进行响应,因此某些费时的操作,如网络连接、下载或者非常占用服务器时间的操作应该放到其他线程。
线程通过java的标准对象Thread 创建. Android 提供了很多方便的管理Android进程的方法:— Looper 在线程中运行一个消息循环; Handler 传递一个消息; HandlerThread 创建一个带有消息循环的线程。
远程调用Remote procedure callsAndroid有一个远程调用(RPCs) 的轻量级机制— 通过这个机制,方法可以在本地调用,在远程执行(在其他进程执行),还可以返回一个值。要实现这个需求,方法调用必须分解方法调用,并且所有要传递的数据必须是操作系统可以访问的级别。从本地的进程和内存地址传送到远程的进程和内存地址并在远程处理和返回。
返回值必须向相反的方向传递。Android提供了做以上操作的代码,所以开发者可以专注于实现RPC的接口。
一个RPC接口只能有一个方法。所有的方法都是同步执行的(直到远程方法返回,本地方法才结束阻塞),没有返回值的时候也是如此。
简单来说,这个机制是这样的:使用IDL (interface definition language).定义你想要实现的接口, aidl 工具可以生成用于java的接口定义,本地和远程都要使用这个定义。它包含2个类,见下图:
inner类包含了所有的管理远程程序(符合IDL描述的接口)所需要的代码。所有的inner类实现了IBinder 接口.其中一个在本地使用。可以不管它的代码;另外一个叫做Stub继承了 Binder 类。为了实现远程调用Android进程,这个类包含RPC接口。开发者可以继承Stub类来实现需要的方法。
一般来说,远程进程会被一个service管理(因为service可以通知操作系统这个进程的信息并和其他进程通信),它也会包含aidl 工具产生的接口文件,Stub类实现了远处那个方法。服务的客户端只需要aidl 工具产生的接口文件。
以下是如何连接服务和客户端调用:
◆服务的客户端(本地)会实现onServiceConnected() 和onServiceDisconnected() 方法,这样,当客户端连接或者断开连接的时候可以获取到通知。通过 bindService() 获取到服务的连接。
◆服务的 onBind() 方法中可以接收或者拒绝连接,取决它收到的intent (intent通过 bindService()方法连接到服务). 如果服务接收了连接,会返回一个Stub类的实例.
◆如果服务接受了连接,Android会调用客户端的onServiceConnected() 方法,并传递一个Ibinder对象(系统管理的Stub类的代理),通过这个代理,客户端可以连接远程的服务。
【编辑推荐】