您的位置:首页 > 移动开发 > Android开发

Android进程、线程、任务、活动栈

2017-05-03 22:02 357 查看

Android进程、线程、任务、活动栈

参考:
http://blog.spinytech.com/2016/11/15/android_multiple_process/

https://developer.android.com/guide/components/processes-and-threads.html#Processes

http://blog.csdn.net/jing_huanhuan/article/details/6167189

 

 

进程:

进程概念

在Android中,一般情况下,一个应用程序就一个进程,这个进程的名称就是应用程序包名。默认情况下,同一应用的所有组件均运行在同一进程中,且大多数应用都不会改变这一点。

Android系统是基于Linux改造而来的,进程系统也是一脉相承。

首先Android会启动一个Linux进程(具体由Zygotefork出来)以及一个主线程,默认的情况下,所有组件都将运行在该进程内。同一个应用由系统分配一个独立的Linux账户,该应用的产生的所有进程,都会是这同一个Linux账户。

通常会使用修改清单文件的android:process来达到多进程的目的。activity、service、receiver 和 provider均支持android:process属性,此属性可以指定该组件应在哪个进程运行,同时根据进程的设置的优先等级我们可以在内存不够时进行清理。

每一个应用程序都是由一些Activity和Service组成的,一般Service运行在独立的进程中,而Activity有可能运行在同一个进程中,也有可能运行在不同的进程中。

 

多进程的好处:

1、分担主进程的内存压力。

我们的应用越做越大,内存越来越多,将一些独立的组件放到不同的进程,它就不占用主进程的内存空间了。比如在启动一个不可见的轻量级私有进程,在后台收发消息,或者做一些耗时的事情,或者开机启动这个进程等。

2、防止主进程被杀守护进程。

守护进程和主进程之间相互监视,有一方被杀就重新启动它。

 

 

多进程带来的问题:

每个进程创建以后,都会拥有独立的空间,独立的VM,所以,很多Java特性都会在多进程开发中失效。

1.静态变量和单例模式完全失效

因为进程间,内存空间是相互独立的,所以VM方法区内的静态变量也都是相互独立的。因为单利模式是基于静态变量的,所以单例也会失效。在两个不同进程访问一个相同类的静态变量,所得的值未必相同,所以在开发中请避免此类代码。

2.线程同步机制完全失效

由于Java的同步机制是VM来进行调度的,两个进程拥有两个不同的VM,所以,同步也会在多进程开发中失效。synchronized关键字、voliate关键字等都是基于VM级别的同步,所以请不要跨进程去使用线程同步。比如主进程有个生产者,子进程的消费者是无法正常使用消费功能的,只能通过跨进程通信,让主进程的消费者去消费,然后再回调。

 

线程:

每个进程有一到多个线程运行在其中。主线程是我们进程中的第一线程。

 

任务和活动栈:

完成用户的一个目的的所有activity 组成一个task,这个task stack任务栈也有人叫活动栈。android系统用一个栈来记录一个任务。有了活动栈,我们就可以通过back键回到上一个activity界面。

 Intent.FLAG_ACTIVITY_NEW_TASK是为了在没有任务栈的环境中重新开启一个新的任务栈,并将task放入该任务栈中。

Eg:Notification 启动Activity时会开启一个task,因为notification他没有在任务栈中,脱离了任务栈开启一个新的task,就需要 Intent.FLAG_ACTIVITY_NEW_TASK。

在任务栈中分前台任务栈和后台任务栈。如果我们去将后台任务栈打开的话,他会合并到前台任务栈中:



看个例子来更深入地学习:

Mainactivity为  A : standard

Activity B:singleTask ,指定任务栈:taskAffinity= “com.test.task1”

Activity  C:SingleTask,指定任务栈:taskAffinity =“com.test.task1”

Eg:A->B->C->A->B->点击返回

因为A为Mainactivity所以启动模式为standard。A启动B因为B为新的栈所以开一新的栈,将B放进去。然后启动C,因为C和B

B栈相同,所以将C放入B的栈。这时候前台栈为“com.test.task1”,后台栈为“包名”,再次启动A,因为前台栈为task1,所以A被放入task1。这时候task1的栈为BCA。当再次启动B的时候,因为B为singleTask需要将BC都出栈(因为singleTask有clearTop的效果)。当B点击返回时task1为空,则进入“包名”的栈。里面有个A,则A出栈。A再点击返回则返回到桌面。

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 线程