Android开发-进程

不管什么操作系统,都有进程这一概念。在Android系统中,也有进程这东西,而且还把分成五类:

1.前台进程

2.可见进程

3.服务进程

4.后台进程

5.空进程


那么是按照什么标准分类的呢?或者说我怎么确定我自己写的应用是属于哪类进程呢?

1.如果某一个应用进程符合下面任意一个条件,那么这个应用进程就属于前台进程

(1) 拥有一个正在与用户交互的Activity。

(2) 拥有一个Service,这个Service绑定了某一个正在与用户交互的Activity。

(3) 拥有一个前台Service。

(4) 拥有一个Service且它正在执行生命周期回调方法。

(5) 拥有一个BroadcatsReceiver且这个BroadcatsReceiver正在执行onReceive方法。

2.如果某一个应用进程符合下面任意一个条件,那么这个应用进程就属于可见进程

(1) 拥有一个可见当不可与用户交互的Activity。

(2) 拥有一个Service,这个Service绑定了一个可见当不可与用户交互的Activity

3.如果某一个应用进程符合下面任意一个条件,那么这个应用进程就属于服务进程

(1) 拥有一个Service,这个Service是通过startService方式开启的。

4.如果某一个应用进程符合下面任意一个条件,那么这个应用进程就属于后台进程

(1) 拥有一个不可见的Activity。

5.如果某一个进程不含有任何应用组件,那么它就是空进程。


注意:假如有一个进程,按照上面的匹配规则,它既符合是前台进程的要求,又符合可见程序的要求,那么它是被认为是属于可见进程的。因为上面的进程分类的优先级是:前台进程 > 可见进程 > 服务进程 > 后台进程 > 空进程,因此会取所有匹配的进程类别中优先级最高的那个作为该进程的进程类别。


Android中把进程划分为这5类进程有什么用呢?

其实就是为了解决在内存(或者其它资源)紧张时确定究竟要先回收掉哪些进程的问题。这5类进程的优先级为:

前台进程 > 可见进程 > 服务进程 > 后台进程 > 空进程

所有在需要回收进程的时候系统会按照从低优先级到高优先级的顺序回收掉进程,当然前台进程和可见进程基本上是不会被回收掉的。

由此可以引申出几个问题:

1.为什么我们建议像下载文件这样的后台操作(不需要界面显示)要开启一个Service,然后在Service中进行?

对于第一个问题,假如我们直接执行后台操作,而不开启一个Service,那么当该进程最小化时(比如说按了Home键),那么该进程很有可能会变为后台进程,注意到后台进程的优先级排在第四,在系统资源紧张时是会回收掉这些进程的,那么此时我们正在进行后台操作的这个后台进程就可能会被kill掉,我们的后台操作也就被终止掉了,当然如果我们是开启的一个Service然后在里面进行后台操作,那么当该进程进入后台时它的优先级还是服务进程,那么在内存紧张时我们的进程被kill掉的几率就会减低,而且如果被服务进程kill掉了,系统在资源充足时会自动重启那些被kill掉的服务进程。

注意:Service是运行在主线程(即UI线程)中的,也就是说,假如我们在Service里面进行耗时操作是可能会导致ANR的。解决方法可以是在Service开启子线程或者使用系统提供的IntentService类等。


2.为什么不能在BroadcastReceiver的onReceive方法中开启子线程进行后台操作?

上面说了,如果一个进程有一个BroadcastReceiver而且正在执行onReceive方法,那么它就是前台进程,优先级最高。但是假如我们在onReceive方法里面创建并开启了一个子线程,那么当onReceive方法执行完之后,该进程的优先级可能会下降,比如说降低为服务进程或者是后台进程,也就是说该进程在内存紧张时被kill掉的几率就会上升,假如该进程真的被kill掉了,那么它创建的所有子线程(当然也包括我们在onReceive方法里面开启的那个线程)也会被kill掉,当然我们在子线程进程的操作就被终止了。解决方法可以是在onReceive方法里开启一个Service,然后在Service里执行后台操作。


还有一个问题:是不是一个App只能拥有一个进程呢?

当然不是,默认情况下一个App是拥有一个进程,不过在需要的时候,你可以让你的App拥有多个进程。比如说现在的QQ程序就有两个进程,当然为什么要创建两个程序不清楚,有人说是互相监控对方状态,如果一方被kill掉了另一方会重新启动被kill掉的进程,虽然这个说法不知道对不对,但是它对我们如何保证我们的应用尽量处于正常运行状态还是很有启发的(Android系统中也有一只Watchdog)。我们注意到在清单文件里,application节点、activity节点、service节点、provider节点和receiver节点都有一个属性叫做process,它是指定该组件所运行的进程名,如果该进程名的进程不存在就会创建一个新的进程。默认情况下application的process属性值是包名,而且下面的所有组件节点的process的属性值与application节点的process属性值是一样的,因此在默认情况下所有的process属性值都是包名,因此整个app就只有一个进程,该进程名为该应用的包名。

既然我们一个App可以拥有多个进程,那么现在我们假设我开发了一个App,它拥有两个进程A和B,假设我们的UI线程在A进程中,现在我在B进程进行耗时操作,比如说Thread.sleep(60 * 1000),那么此时应用程序会产生ANR吗?当然不会!因为我们进行的耗时操作是在另一个进程(确切说是这个进程的某一个线程)中,并没有在UI线程中进行,因此是不会产生ANR的。


其它

1.空进程是为了加快下一次程序启动的速度,毕竟重新创建一个进程并初始化一些东西是比较耗费时间的。

2.代码都是运行在线程中,一个进程里可以创建多个线程,比如默认情况下我们的App进程就创建了一个UI线程,然后代码在该UI线程中执行。


转载请注明原文地址:http://blog.csdn.net/u012619640/article/details/48396603

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值