Android developer dev guide 应用程序基础之processes and threads

2010-05-09 19:41:09

 

 

第三部分是线程和进程的内容,内容比较少,熟悉操作系统的人可以不用看了

电子版已经上传,http://download.csdn.net/source/2333509

 

 

 

 

 

Android 开发者

应用程序基础

 

——————————————————————————————————

进程和线程

当应用程序第一个元件要运行时, Android 为其启动一个单线程执行的 Linux 进程。默认地,应用的所有元件在该进程和线程中运行。

然而,你能安排元件在其他进程中运行,还能给任何进程产生额外的线程。

 

进程

元件运行的进程由清单文件控制。元件元素—— <activity> <service> <receiver> <provider> ——每个都有 process 属性,能指定元件应当运行的进程。这些属性能设置使每个元件运行在自己的进程中,或者使一些元件共享一个进程的同时其它元件独立运行。它们也能设置成使不同应用的元件在同一个进程中运行——只要这些应用共享一个 Linux 用户 ID 并且分配了相同权限。 <application> 元素也有一个 process 属性,用来设置应用到所有元件的默认值。

所有元件在指定进程中的主线程里实例化,这些元件的系统调用从主线程中发出。不会为每个实例创建单独的线程。所以,响应这些调用的方法——像报告用户动作的 View.onKeyDown() 方法和在后面元件生命周期 部分讨论的生命周期通知——通常在进程的主线程运行。这意味着,当系统调用时,元件不能执行长时间或者阻塞的操作(比如网络操作和运算循环),因为这会阻塞在进程中的其他元件。你可以产生单独的线程来执行长时间操作,在下面的线程 部分讨论。

Android 可能会在某些场合关闭进程,当内存太低和更迫切的用户服务的进程请求时。结果就是在进程中运行应用程序元件被销毁。当那些元件还有工作要做时,就重新开始一个进程。

当决定终止那些进程时, Android 权衡它们和用户相关的重要程度。比如,关掉一个不在屏幕上显示的活动进程比关掉显示着的容易。所以,是否终止进程的决定依靠元件在进程中运行的状态。这些状态是下面部分的话题,元件的生命周期

 

线程

即使你可能会想限制你的应用为单进程,依旧很可能有你需要产生线程来完成后台工作的时候。因为用户界面必须对用户动作进行反应,用于活动的线程就不应当用于时间消耗的工作,比如网络下载。所有不能迅速完成的工作都应分配到不同的线程去。

线程用标准 Java Thread 对象创建。 Android 提供一系列方便的类来管理线程—— Looper 运行线程中的消息循环, Handler 处理消息, HandlerThread 建立消息循环的线程。

 

远程程序调用

Android 为远程程序调用( RPCs )提供了轻量级机制——本地方法调用,远程执行(在其他进程),返回结果给调用者。这意味着,分解调用方法和它需要的数据到操作系统能理解的层次,从本地进程和地址空间传输到远程进程和地址空间,重新集合和使能调用。返回值反向传输。 Android 提供了做完成该工作的所有代码,所以你能集中精力在定义和执行 RPC 接口本身。

RPC 接口只能包含方法。所有方法同步执行(本地方法阻塞直到远程方法完成),即使没有返回值。

简要地说,该机制按以下步骤工作:开始用简单的 IDL (接口定义语言)声明你要执行的 RPC 接口。从该声明中, aidl 工具生成 Java 接口定义,必须对本地和远程进程都可用。它包含两个内部类,如下图所示:

 

内部类有管理你用 IDL 声明的接口的远程程序调用所需要的所有代码。两个内部类都执行 IBinder 接口。其中一个供系统本地和内部使用;你写的代码可以忽略它。另一个,叫做 Stub ,继承 Binder 类。为了补充实现 IPC 调用的内部代码,它包含了你声明的 RPC 接口的方法声明。你可以用 Stub 的子类执行这些方法,如图所示。

典型地,远程进程由一个服务管理(因为服务可以通知系统进程和它与其他进程的连接)。它有 aidl 工具生成的和执行 RPC 方法的 Stub 子类两者的接口文件。服务的客户只有 aidl 工具生成的接口文件。

 

这里是服务和客户的连接如何建立的:

l   服务的客户(本地)会执行 onServiceConnected() onServiceDisconnected() 方法,使他们可以知道何时建立一个到远程服务的连接,何时断开连接。它们然后调用 bindService() 建立连接。

l   执行服务的 onBind() 方法接受或者拒绝连接,根据它接受的意图(该意图传递给 bindService() )。如果连接被接受,它返回一个 Stub 子类的实例。

l   如果服务接受连接, android 调用客户的 onServiceConnected() 方法并传递一个 IBinder 对象,由服务管理的 Stub 子类的代理。通过代理,客户可以调用远程服务。

 

这个简短的介绍跳过了 RPC 机制的细节。更过内容见使用 AIDL 设计远程接口 IBinder 类的描述。

 

线程安全的方法

在一些情况下,你执行的方法会被超过一个线程调用,所以必须是线程安全的。

这主要针对可以远程调用的方法——如前面部分讨论的 RPC 机制。当调用以 IBinder 对象实现的方法在和 IBinder 相同的进程中产生时,方法在调用者的线程中执行。然而,当调用在其他进程中产生,方法在线程库中的一个线程中执行, Android 在和 IBinder 相同的进程中维持这个线程库;它不在服务进程的主线程中执行。比如,虽然一个服务的 onBind() 方法在服务进程的主线程中调用, onBind() 返回对象上(比如,实现 RPC 方法的 Stub 子类)实现的方法在库中的线程调用。因为服务可以有多个客户,那么就有多个库线程同时使用同一个的 IBinder 方法。因此 IBinder 方法必须实现线程安全。

相似的,内容供给能收到其他进程中产生的数据请求。虽然内容解析和内容供给类隐藏了内部进程通信管理的细节,响应那些请求的内容供给的方法—— query() insert() delete() update() getType() 方法——从内容供给的进程的线程库中调用,而不是主线程。因为这些方法可以被多个线程同时调用,所以它们必须是线程安全的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值