Android学习知识Android开发手机移动程序开发

关于Android进程的那些事儿

2017-02-28  本文已影响224人  b923228cc7b5

最近项目中需要接入一个SDK,这个SDK会开启一个新进程,但是它自身的初始化要在app的主进程中进行。由于对进程的理解不够,导致我在此坑中挣扎了整整一个礼拜,痛定思痛,终于下定决心研究一下进程。


1. 什么是进程

进程占有一定的资源空间,内部资源共享,一个进程至少包含一个线程。但是线程没有独立的内存空间,而是在它所在的进程中资源共享。也正是这个原因,有时候我们需要考虑到线程安全的问题,避免在不同线程中对同一个资源文件进行操作导致的冲突。

在安卓中,一个应用启动时会新建一个进程,该进程由zgoate进程fork出来,具体过程参照Android的系统启动流程和应用启动流程这篇文章。


2.进程与线程的区别

线程(Thread)、进程(Process)这俩货中文翻译都有一个“程”字,但是不代表二者有很多的共同点。我举一个例子,大家就明白了。

工厂=CPU

如果把CPU比作一座工厂,内存比作工厂的占地面积,那么,进程就是工厂的车间,线程就是车间里的工人。那么,他们之间的对应关系如下:

详细内容参照这篇文章http://blog.csdn.net/yapian8/article/details/41015631


3. 进程分类

按优先级由高到低分为5类:

进程优先级金字塔

3.1 前台进程:

用户当前操作所必需的进程。

前台进程一般是visble(可见的)但要注意,visible不一定是active的。比如activity弹出一个dialog,那么activity可见但是inactive,dialog变成active。

3.2 可见进程:

没有任何前台组件、但仍会影响用户在屏幕上所见内容的进程。
比如弹出dialog后面的activity。

3.3 服务进程:

正在运行的Service。

由于运行服务的进程其级别高于托管后台 Activity 的进程,因此启动长时间运行操作的 Activity 最好为该操作启动服务,而不是简单地创建工作线程,当操作有可能比 Activity 更加持久时尤要如此。否则,后台的Activity被销毁时,工作线程也会被销毁,导致后台操作的失败。

例如,正在将图片上传到网站的 Activity 应该启动服务来执行上传,这样一来,即使用户退出 Activity,仍可在后台继续执行上传操作。使用服务可以保证,无论 Activity 发生什么情况,该操作至少具备“服务进程”优先级。 同理,广播接收器也应使用服务,而不是简单地将耗时冗长的操作放入线程中。

3.4 后台进程:

已经调用onStop方法的activity。正如3.3中所提到的,避免因为后台进程的销毁导致后台任务的中断。

3.5 空进程:

不包含任何应用组件的进程

总之,时刻注意四大组件的生命周期,避免因为GC(Garbage Collection)问题导致关键性的操作失败。


4. 为什么需要多进程

一个应用默认只有一个进程,进程名称就是包名,每个进程都有自己独立的资源和内存空间,系统给每个进程分配的内存大小是有限制的,当进程占用内存超过限制时,就会报OOM的错误。

OOM的问题的解决方法:


5. 进程间通信(IPC: InterProcess Communication)

因为每个进程都有自己独立的资源和内存空间,所以堆栈信息,文件操作都是独立的,这就需要用到IPC。IPC实现方式通常有如下几种:

5.1 Activity.

通过指定Activity的action,访问其他进程的Activity,通过Intent或者Uri来传递数据。

5.2 ContentProvider

多个应用程序之间使用文件或者Sqlite共享数据,利用ContentProvider实现对数据的增删改查。

5.3 BroadCast

类似Activity,通过Intent传递数据,

5.4 Service

Service有两个作用:后台运行和跨进程通信。其中跨进程通信是通过AIDL(Android Interface Definition Language)服务实现的。

上述四种方式分别对应Android四大组件,一张图表示


Activity,Service,BroadCast Receiver,ContentProvider实现IPC

5.5 Messenger

当您需要执行 IPC 时,为您的接口使用 Messenger要比使用 AIDL 实现它更加简单,因为 Messenger会将所有服务调用排入队列,而纯粹的 AIDL 接口会同时向服务发送多个请求,服务随后必须应对多线程处理。

对于大多数应用,服务不需要执行多线程处理,因此使用Messenger 可让服务一次处理一个调用。如果您的服务必须执行多线程处理,则应使用 AIDL 来定义接口。

Messenger实现IPC

限于篇幅,IPC实现方式的具体步骤和原理不再展开,有空再写一篇关于进程间通信的文章。当然如果嫌麻烦,可以使用别人封装好的框架,比如EventBus之类。


另外,最后两张图的来源自下面这个帅哥,有兴趣可以关注他,https://github.com/yinshijian-kkb/stay4android/blob/master/Binder%E6%A1%86%E6%9E%B6%E8%A7%A3%E6%9E%90.md

Aleksandar Gargenta
上一篇下一篇

猜你喜欢

热点阅读