Android 进程与线程总结

说起进程与线程大家心里想必还是有点概念的,但是却说不清楚。
什么一条进程里面多条线程,学过Java的都知道异步线程这个十分重要的技术。但是真要实实在在说清楚他们的概念,区别,关联等等,还是很难的。
本文将结合百度,博客等,对Android的进程与线程进行一次全面的总结。

进程

是一个具有独立功能的程序关于某个数据集合的一次运行活动。进程是系统进行资源分配和调度的一个独立单位。可以申请和拥有系统资源,是一个动态的概念,是一个活动的实体,是一个“执行中的程序”。不只是程序的代码,还包括当前的活动。
在默认情况下同一app的所有组件都是运行在同一进程中的,而且大多数app并不需要去更改这个设定。但如果我们真的需要指定进程来运行特定组件,那么可以在manifest文件中设置。我们在manifest文件中定义了各个组件,例如activity,service,receiver,provider等等,我们可以设置process属性来指定一个新线程来运行该组件。通过设置process属性,我们可以设置每个组件都运行在不同的进程中,也可以指定几个组件运行在同一个进程中。我们甚至可以设置不同来自app的组件运行在同一个进程中(通过指定相同的process属性并共享相同的user ID)。

进程的生命周期
  1. 前台进程foreground process:当前正在与用户交互的进程。
  2. 可见进程Visable process:没有任何前台组件在此进程中运行,但是仍然可以影响到用户所看到的屏幕。
  3. 服务进程service process:例如音乐播放,文件下载等等。
  4. 后台进程background process:无法直接影响到用户体验,系统可能随时杀死此类进程回收内存供以上三种进程使用。
  5. 空进程empty process:该进程中没有运行任何组件,保持此类进程存在的唯一原因就是等待任务。一旦有组件需要运行,则可以缩短进程启动时间。
进程通信
  1. Bundle
    四大组件中三大组件Activity、Service、Receiver都支持在Intent中传递Bundle数据。
    由于Bundle实现了Parcelable接口,所以它可以很方便的在不同的进程间传输数据。当然我们传输的数据必须能够被序列化,比如基本类型、实现了Parcelable接口的对象、实现了Serializable接口的对象以及一些Android支持的特殊对象。

  2. 使用文件共享/数据库
    两个进程通过读写同一个文件来交换数据,比如A进程把数据写入文件,B进程通过读取这个文件来获取数据。
    Android系统基于Linux,使得并发读写文件可以没有限制的进行,甚至两个线程同时对文件读写操作都是允许的,尽管可能出问题,因此文件共享方式适合在对数据同步要求不高的进程间进行通信。
    SharedPreferences也属于文件的一种,但是由于系统对它的读写有一定的缓存策略,即在内存中会有一份SharedPreferences文件的缓存;因此在多进程模式下,系统对它的读写就变得不可靠,会有很大几率丢失数据,不建议在进程间通信中使用SharedPreferences。

  3. Messenger
    Messenger可以理解为信使,通过它可以再不同进程中传递Message对象,在Message中放入我们需要传递的数据,就可以实现数据的进程间传递了。
    Messenger是一种轻量级的IPC方案,它的底层实现是AIDL。由于它一次处理一个请求,因此在服务端不需要考虑线程同步的问题,因为服务端不存在并发执行的情形。

  4. 使用AIDL
    AIDL是 Android Interface definition language的缩写,它是一种android内部进程通信接口的描述语言。AIDL可以处理发送到服务器端大量的并发请求(不同与Messenger的串行处理方式),也可以实现跨进程的方法调用。
    在Android中使用方法:创建一个Service和一个AIDL接口,接着创建一个类继承自AIDL接口中的Stub类并实现Stub中的抽象方法,在Service的onBind方法中返回这个类的对象,然后客户端绑定服务端Service,建立连接后就可以访问远程服务器了。

  5. 使用ContentProvider
    ContentProvider是Android中提供的专门用于不同应用间进行数据共享的方式,天生适合进程间通信。
    ContentProvider的底层实现也是Binder,但是它的使用过程比AIDL简单的多,因为系统做了封装,使得无需关心细节即可轻松实现IPC。ContentProvider主要以表格的形式组织数据,和数据库很类似,但ContentProvider对底层的数据存储方式没有任何要求,既可以使用Sqlite数据库,也可以使用文件方式,甚至可以使用内存中的一个对象来存储。

  6. Socket
    Socket套接字,是网络通信中的概念,分为流式套接字和用户数据奥套接字两种,对应于网络的传输控制层中的TCP和UDP协议。
    两个进程可以通过Socket来实现信息的传输,Socket本身可以支持传输任意字节流。

  7. BroadcastReceiver

线程

当应用程序启动后,系统将会创建一个主线程来运行应用程序。主线程非常重要,它负责为适当的用户控件分发任务和事件,包括绘制任务等等。同时,主线程也负责UI组件和应用程序的交互,所以我们也称主线程为UI线程。
除了主线程之外,耗时操作都应该规范到子线程中,线程之间会有相应的通信方式,但相互独立。
系统并不会为每个组件单独开启一个线程来运行,所有的组件都会在主线程中初始化并运行运行在同一个进程中,系统通过主线程来调用每个组件。所以,系统回调方法(例如onKeyDown,生命周期回调方法等)通常运行于主线程。

线程间通信
  1. 全局变量
  2. Handler机制
  3. 使用AsyncTask
  4. View.postDelay(Runnable , long)
  5. runOnUiThread(Runnable)
runOnUiThread(new Runnable(){//更新UI
                    @Override
                    public void run() {
                    //更新UI
                    }    
                });

进程与线程的关系与区别

  1. 子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间,每个线程有自己的执行堆栈和程序计数器为其执行上下文。
  2. 进程间相互独立,同一进程的各线程间共享。某进程内的线程在其它进程不可见。
  3. 进程间通信IPC,线程间可以直接读写进程数据段(如全局变量)来进行通信——需要进程同步和互斥手段的辅助,以保证数据的一致性。
  4. 线程上下文切换比进程上下文切换要快得多。
  5. 在操作系统中进程是OS分配资源的最小单位,而线程是执行任务的最小单位。
  6. 一个进程可以拥有多个线程执行任务,这些线程可以共享该进程分配到的资源。
  7. 当我们的app启动运行后,在该app没有其他组件正在运行的前提下,Android系统会启动一个新Linux进程来运行app,这个进程只包含了一个线程在运行。在默认情况下,app的组件都运行在该进程中,最初就包含的这个线程也被称为主线程或者UI线程。
  8. 线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。线程比进程更小,基本上不拥有系统资源,故对它的调度所用资源小,能更高效的提高系统内多个程序间并发执行的。

本文参考

http://www.cnblogs.com/pear-lemon/p/6547734.html
http://www.cnblogs.com/cqumonk/p/4828616.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值