引言
当应用程序的组件第一次运行时,Android将启动一个只有一个执行线程的Linux进程。默认,应用程序所有的组件运行在这个进程和线程中。然而,你可以安排组件运行在其他进程中,且你可以为进程衍生出其它线程。本文从下面几点来介绍Android的进程与线程:
- 1、进程
- 2、线程
- 2.1、远程过程调用(Remote procedure calls,RPCs)
- 2.2、线程安全方法
1、进程
组件运行于哪个进程中由清单文件控制。组件元素——<activity>
、<service>
、<receiver>
、<provider>
,都有一个process
属性可以指定组件运行在哪个进程中。这个属性可以设置为每个组件运行在自己的进程中,或者某些组件共享一个进程而其他的不共享。他们还可以设置为不同应用程序的组件运行在同一个进程中——假设这些应用程序共享同一个Linux用户ID且被分配了同样的权限。<application>
元素也有process
属性,为所有的组件设置一个默认值。
所有的组件都在特定进程的主线程中实例化,且系统调用组件是由主线程派遣。不会为每个实例创建单独的线程,因此,对应这些调用的方法——诸如View.onKeyDown()
报告用用户的行为和生命周期通知,总是运行在进程的主线程中。这意味着,没有组件当被系统调用时应该执行很长时间或阻塞操作(如网络操作或循环计算),因为这将阻塞进程中的其它组件。你可以为长操作衍生独立的线程。
public boolean onKeyDown
(int keyCode,KeyEvent event):默认实现KeyEvent.Callback.onKeyMultiple(),当按下视图的KEYCODE_DPAD_CENTER或KEYCODE_ENTER然后释放时执行,如果视图可用且可点击。
参数
keyCode
-表示按钮被按下的键码,来自KeyEvent
event
-定义了按钮动作的KeyEvent对象
返回值
如果你处理事件,返回true;如果你想下一个接收者处理事件,返回false。
当内存剩余较小且其它进程请求较大内存并需要立即分配,Android要回收某些进程,进程中的应用程序组件会被销毁。当他们再次运行时,会重新开始一个进程。
当
决定终结哪个进程时,Android会权衡他们对用户重要性的相对权值。例如,与运行在屏幕可见的活动进程相比(前台进程),它更容易关闭一个进程,它的
活动在屏幕是不可见(后台进程)。决定是否终结进程,取决于运行在进程中的组件状态。关于组件的状态,将在后面一篇——组件生命周期
中介绍。
2、线程
虽然你可能会将你的应用程序限制在一个进程中,但有时候你会需要衍生一个线程做一些后台工作。因为用户界面必须很快地响应用户的操作,所以活动寄宿的线程不应该做一些耗时的操作如网络下载。任何不可能在短时间完成的操作应该分配到别的线程。
线程在代码中是用标准的Java线程对象创建的,Android提供了一些方便的类来管理线程——Looper
用于在线程中运行消息循环、Handler
用户处理消息、HandlerThread
用户设置一个消息循环的线程。
Looper类
该
类用户在线程中运行消息循环。线程默认没有消息循环,可以在线程中调用prepare()创建一个运行循环;然后调用loop()处理消息直到循环结束。
大部分消息循环交互是通过Handler类。下面是一个典型的执行一个Looper线程的例子,分别使用prepare()和loop()创建一个初始的
Handler与Looper交互:
class
LooperThread extends
Thread {
public
Handler mHandler;
public
void
run() {
Looper.prepare();
mHandler = new
Handler() {
public
void
handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
更多的关于Looper
的信息及Handler、HandlerThread
请参阅相关资料。
2.1、远程过程调用(Remote procedure calls,RPCs)
Android
有一个轻量级的远程过程调用机制——方法在本地调用却在远程(另外一个进程中)执行,结果返回给调用者。这需要将方法调用和它伴随的数据分解为操作系统能
够理解的层次,从本地进程和地址空间传输到远程进程和地址空间,并重新组装调用。返回值以相反方向传输。Android提供了做这些工作的所有代码,这样
我们可以专注于定义和执行RPC接口本身。
一个RPC接口仅包含方法。所有的方法同步地执行(本地方法阻塞直到远程方法执行完成),即
使是没有返回值。简言之,该机制工作原理如下:首先,你用简单的IDL(interface definition
language,接口定义语言)声明一个你想实现的RPC接口。从这个声明中,aidl
工具生成一个Java接口定义,提供给本地和远程进程。它包含两个内部类,如下图所示:
内部类有管理你用IDL定义的接口的远程过程调用所需要的所有代码。这两个内部类都实现了IBinder
接口。其中之一就是在本地由系统内部使用,你写代码可以忽略它。另外一个是Stub
,扩展自Binder
类。除了用于有效地IPC(interprocess communication)调用的内部代码,内部类在RPC接口声明中还包含方法声明。你可以定义Stub
的子类实现这些方法,如图中所示。
通常情况下,远程过程有一个服务管理(因为服务能通知系统关于进程和它连接的其它进程的信息)。它有由aidl
工具生成的接口文件和Stub
子类实现的RPC方法。服务的客户端仅有由aidl
工具生成的接口文件。
下面介绍服务如何与它的客户端建立连接:
- 服务的客户端(在本地端的)应该实现onServiceConnected()
和onServiceDisconnected()
方法,因此当与远程服务建立连接成功和断开连接是会通知它。然后调用bindService()
建立连接。
- 服务的onBind()方法将实现为接受或拒绝连接,者取决于它接受到的意图(该意图传送到binServive())。如果连接被接受,它返回一个Stub
子类的实例。
- 如果服务接受连接,Android调用客户端的onServiceConnected()方法且传递给它一个IBinder对象,返回由服务管理的Stub
子类的一个代理。通过代理,客户端可以调用远程服务。
这里只是简单地描述,省略了一些RPC机制的细节。你可以查阅相关资料或继续关注Android开发之旅,后面将为你奉上。
2.2、线程安全方法
在一些情况下,你实现的方法可能会被不止一个线程调用,因此必须写成线程安全的。这对远程调用方法是正确的——如上一节讨论的RPC机制。当从IBinder
进程中调用一个IBinder
对象中实现的一个方法,这个方法在调用者的线程中执行。然而,当从别的进程中调用,方法将在Android维护的IBinder
进程中的线程池中选择一个执行,它不在进程的主线程中执行。例如,一个服务的onBind()
方法在服务进程的主线程中被调用,在onBind()
返回的对象中执行的方法(例如,实现RPC方法的Stub
子类)将在线程池中被调用。由于服务可以有一个以上的客户端,所以同时可以有一个以上的线程在执行同一个IBinder
方法。因此,IBinder
的方法必须是线程安全的。
同样,一个内容提供者可以接受其它进程产生的数据请求。虽然ContentResolver
和 ContentProvider
类隐藏进程通信如何管理的,对应哪些请求的ContentResolver
方法——query()、insert()、delete()、update()、getType(),在内容提供者的进程的线程池中被调用,而不是在这一进程的主线程中。因为这些方法可以同时从任意数量的线程中调用,他们也必须实现为线程安全的。
分享到:
相关推荐
Android开发之旅:进程与线程 7 Android开发之旅:组件生命周期(一) 8 Android开发之旅:组件生命周期(二) 9 Android开发之旅:组件生命周期(三) 10 Android 开发之旅:又见Hello World!11 Android 开发...
### Android开发之旅知识点详解 #### 一、环境搭建及HelloWorld **1.1 JDK安装** JDK(Java Development Kit)是开发Java程序的基础工具包,对于Android开发来说至关重要。 - **下载**: 访问Oracle官网或其他...
【Android 开发之旅:环境搭建】 在Android开发的初期阶段,首要任务是建立一个完整的开发环境。这包括安装Java Development Kit (JDK),Eclipse集成开发环境,Android Software Development Kit (SDK)以及Android ...
【Android开发之旅(2): Android架构】 Android架构是构建Android应用程序的基础,它由五个主要部分组成,分别是Linux Kernel、Android Runtime、Libraries、Application Framework和Applications。这些组件共同协作...
在Android开发之旅中,我们已经探索了许多核心概念和组件,为深入学习打下了坚实的基础。首先,我们了解了Android应用程序的基本目录结构,其中包括src、gen、Android x、assets、AndroidManifest.xml以及default....
《老罗的Android之旅》是一套深受Android开发者欢迎的学习资源,由知名技术讲师老罗精心制作。这个压缩包集合了该课程的多个关键主题的PPT文件,旨在为那些希望深入理解Android系统的开发者提供一站式学习材料。以下...
在Android开发过程中,深入理解Android架构对于提升开发效率和代码质量至关重要。Android系统架构主要分为五个部分:Linux Kernel、Android Runtime、Libraries、Application Framework和Applications。本文将逐一...
《老罗的Android之旅》是一份深入探讨Android操作系统核心概念的教学资料,主要涵盖了Android应用程序的各个方面,包括UI架构、组件设计、虚拟机、消息处理、硬件抽象层、安全防护、输入事件处理、资源管理和进程...
**金典的老罗的android之旅**是一段深入探索Android世界的精彩旅程,专为对Android开发感兴趣的初学者和进阶者量身打造。这个资源集合涵盖了Android开发的关键领域,旨在通过一系列精心编排的PPT文档,帮助学习者...
《老罗Android之旅》是一份由知名科技人士老罗精心准备的Android技术分享课程,旨在帮助初学者和有经验的开发者深入理解Android操作系统的核心概念、开发技巧以及实战应用。这份授课PPT课件包含了丰富的知识内容,...
通过这个压缩包中的“android开发入门.pdf”,你将能够系统地学习并逐步精通Android开发,开启你的移动开发之旅。记住,实践是最好的老师,理论结合实际操作,才能真正成为Android开发的行家里手。祝你学习顺利,...
Android系统是全球最广泛使用的移动操作系统之一,它基于Linux内核,为智能手机、平板电脑以及智能电视等设备提供丰富的...希望这个“Android系统原理与开发要点详解”能帮助你开启Android开发之旅,并在其中不断成长。
在Android应用开发的世界里,初学者常常被众多的概念和技术细节所困扰。"Android应用开发详解d88 android入门"是一个适合新手的引导...通过这个入门教程,你可以逐步掌握Android开发的基础,开启你的移动应用开发之旅。
在进入Android 2.2(Froyo)开发环境配置的详细步骤之前,先要了解一下为何这个版本在Android的历史上如此重要。...通过这些步骤,初学者可以快速建立起自己的开发环境,开始Android应用的开发之旅。
总结,Android 4.4源码的学习是一次深入操作系统底层的探索之旅,它涵盖了操作系统、软件工程、硬件交互等多个领域。通过解析和理解源码,开发者不仅可以提升技术水平,还能为优化应用性能、开发定制系统提供有力...
8. **操作系统**:进程与线程、内存管理、文件系统、操作系统的调度算法等。 9. **安全知识**:网络安全基础,如加密算法、漏洞防范、SQL注入、XSS攻击等。 10. **移动开发**:iOS(Swift/Objective-C)或Android...
Android 2.2,也称为Froyo(冻酸奶),是Android操作系统的一个重要版本,它在2010年发布,带来了许多性能提升和新功能。...这是一次宝贵的探索之旅,可以为Android开发者的技能树添加重要的分支。
总的来说,Android 4.1.2源码的学习是一次对操作系统底层机制的探索之旅,对于提升开发者的技术水平和创新能力具有重大意义。通过对Jelly Bean源码的深入研究,我们可以发现许多关于Android系统优化和性能提升的秘诀...
《深入剖析Android 2.3源码:src的探索之旅》 Android 2.3,代号Gingerbread,是Android系统的一个重要版本,它的源码揭示了Android系统内部的运行机制,为开发者提供了深入了解和定制系统的机会。本文将围绕...