Android中的进程与线程
一、简介
应用启动时,Android 系统会为应用启动新的 Linux 进程。默认情况下,同一应用的所有组件在相同的进程和线程(称为“主”线程)中运行。 但是,也可以设置应用中的其他组件在单独的进程中运行,并为任何进程创建额外的线程。
二、进程
2.1设置组件的进程
AndroidManifest文件中的<activity>、<service>、<receiver> 和 <provider>标签均支持android:process 属性,此属性可以指定该组件应在哪个进程运行。
注意:对于不同应用的组件,还可以设置相同的android:process,使其在同一进程中运行,但前提是这些应用共享相同的UserId并且具有相同的签名。
2.2 进程的重要性等级
当Android系统回收内存时,会根据进程的重要性顺序回收。Android系统对进程的重要性有五个级别,分别是前台进程、可见进程、服务进程、后台进程、空进程。系统会根据进程中正在运行的组件以及这些组件的状态,将每个进程放入“重要性层次结构”中。
-
前台进程
进程中有正在与用户交互的Activity(已调用 Activity 的 onResume() 方法)
进程中有和前台Activity绑定的Service
进程中有前台Service(服务已调用 startForeground())
进程中正执行Service的生命周期方法(onCreate,onStart,onDestroy)
进程中有正执行其 onReceive() 方法的 BroadcastReceiver -
可见进程
托管不在前台、但仍对用户可见的 Activity(已调用其 onPause() 方法)。
托管绑定到可见(或前台)Activity 的 Service -
服务进程
正在运行已使用 startService() 方法启动的服务且不属于上述两个更高类别进程的进程。 -
后台进程
包含目前对用户不可见的 Activity 的进程(已调用 Activity 的 onStop() 方法)。 -
空进程
不含任何活动应用组件的进程。保留这种进程的的唯一目的是用作缓存,以缩短下次在其中运行组件所需的启动时间。
2.3 进程间通信
Android 利用远程过程调用 (RPC) 提供了一种进程间通信 (IPC) 机制,通过这种机制,由 Activity 或其他应用组件调用的方法将(在其他进程中)远程执行,而所有结果将返回给调用方。这就要求把方法调用及其数据分解至操作系统可以识别的程度,并将其从本地进程和地址空间传输至远程进程和地址空间,然后在远程进程中重新组装并执行该调用。 然后,返回值将沿相反方向传输回来。 Android 提供了执行这些 IPC 事务所需的全部代码,因此您只需集中精力定义和实现 RPC 编程接口即可。
三、线程
应用启动时,系统会为应用创建一个名为“主线程”的执行线程。 此线程非常重要,是应用与 Android UI 进行交互的线程,负责响应用户交互事件,主线程有时也称为 UI 线程。
Android 的单线程模式必须遵守两条规则:
不要阻塞 UI 线程(特别Android禁止网络操作放在UI线程)
不要在 UI 线程之外访问 Android UI(因为UI方法是线程不安全的)
3.1 工作线程
要保证应用 UI 的响应能力,关键是不能阻塞 UI 线程。如果执行的操作不能很快完成,则应确保它们在单独的线程(“后台”或“工作”线程)中运行。
Android 提供了几种途径来从其他线程访问 UI 线程。以下列出了几种有用的方法:
- Activity.runOnUiThread(Runnable)
- View.post(Runnable)
- View.postDelayed(Runnable, long)
- Handler机制访问UI线程
- AsyncTask类
3.2 线程安全方法
对于实现的方法可能在多线程中调用的,要注意线程安全。比如:
绑定服务中提供的远程调用方法和内容提供程序接收来自其他进程的数据请求。