前言:碎片化学习是不好的习惯,必须整理总结成自己的知识体系
一.进程,线程
- 进程与线程之间的关系
从操作系统的角度来说:进程是系统资源分配的基本单位,线程是CPU调度最小的调度单位.一个进程可以包含多个线程。
从应用进程的角度来说:一个应用进程被Zygote fork出来,就已经有了一些默认的线程,比如最重要的a)主线程:应用的生命周期函数都是在主线程中调用;b)binder线程:binder线程是应用中最重要的基础线程,它负责与ams跨进程沟通,完成组件的创建,启动,销毁,同时请求系统的服务,如JobSchecduleService.
eg-1:system_server进程中的众多线程
system 2050 632 281384 148564 unix_strea 0000000000 S system_server//system_server进程,手机中最重要的进程,系统服务的大管家。
system 2052 2050 2381384 148564 do_sigtime 0000000000 S Signal Catcher
system 2054 2050 2381384 148564 futex_wait 0000000000 S ReferenceQueueD
system 2056 2050 2381384 148564 futex_wait 0000000000 S FinalizerDaemon
system 2058 2050 2381384 148564 futex_wait 0000000000 S FinalizerWatchd
system 2060 2050 2381384 148564 futex_wait 0000000000 S HeapTaskDaemon
system 2593 2050 2381384 148564 binder_thr 0000000000 S Binder:2050_1
system 2600 2050 2381384 148564 binder_thr 0000000000 S Binder:2050_2
system 2938 2050 2381384 148564 SyS_epoll_ 0000000000 S android.bg
system 2939 2050 2381384 148564 SyS_epoll_ 0000000000 SActivityManager
system 2940 2050 2381384 148564 SyS_epoll_ 0000000000 S android.ui
system 2941 2050 2381384 148564 SyS_epoll_ 0000000000 S ActivityManager
system 2942 2050 2381384 148564 SyS_epoll_ 0000000000 S android.fg
system 2943 2050 2381384 148564 inotify_re 0000000000 S FileObserver
system 2944 2050 2381384 148564 SyS_epoll_ 0000000000 S android.io
system 2945 2050 2381384 148564 SyS_epoll_ 0000000000 S android.display
system 2946 2050 2381384 148564 futex_wait 0000000000 S CpuTracker
system 2947 2050 2381384 148564 SyS_epoll_ 0000000000 SPowerManagerSer
system 2948 2050 2381384 148564 pm_get_wak 0000000000 S system_server
system 2949 2050 2381384 148564 futex_wait 0000000000 S BatteryStats_wa
system 3005 2050 2381384 148564 SyS_epoll_ 0000000000 SPackageManager
eg-2:一个应用进程中的众多线程:
USER PID PPID VSIZE RSS WCHAN PC NAME
u0_a55 4104 308 772924 28336 sys_epoll_ b6d2999c S com.xxx.xxx//主进程,进程ID为(4104)
u0_a55 4109 4104 772924 28336 do_sigtime b6d29c70 S Signal Catcher//这个线程是用来捕获linux信号和做一些后续处理的。如SIGBUS
u0_a55 4110 4104 772924 28336 poll_sched b6d29b8c S JDWP
u0_a55 4111 4104 772924 28336 futex_wait b6d00644 S ReferenceQueueD
u0_a55 4112 4104 772924 28336 futex_wait b6d00644 S FinalizerDaemon
u0_a55 4113 4104 772924 28336 futex_wait b6d00644 S FinalizerWatchd
u0_a55 4114 4104 772924 28336 futex_wait b6d00644 S HeapTaskDaemon
u0_a55 4115 4104 772924 28336 binder_thr b6d29ac8 S Binder:4104_1//binder线程池
u0_a55 4116 4104 772924 28336 binder_thr b6d29ac8 S Binder:4104_2
u0_a55 4121 4104 772924 28336 inotify_re b6d2a978 S FileObserver
u0_a55 4124 4104 772924 28336 sys_epoll_ b6d2999c S local_job_dispa
u0_a55 4164 4104 772924 28336 sys_epoll_ b6d2999c S remote_job_disp
2. Android中的多进程模型
[2.1] Android 中的多进程一般指一个应用中存在多个进程的情况.
我们可以通过指定android :process属性,让一个应用的不同组件运行在指定进程。
<service
android:process=":remote" >
</service>
以“:”开头的进程属于当前应用的私有进程,其它应用的组件不能通过ShareUID与它跑在一个进程
<service
android:process=":com.xxx.xxx.remote" >
</service>
指定全名的进程属于全局进程。其它应用的组件可以通过ShareUID与它跑在一个进程.
[2.2]多进程带来的问题
Android 为每个应用进程分配了一个独立的虚拟机,不同的虚拟机在内存分配上有不同的地址空间,所以运行在不同进程中的 。四大组件是不同通过内存来共享数据。多进程之间组件一定要共享数据吗?不一定,但是我们只要使用多进程模型,一般都是 需要跨进程通信的。
一般来说,使用多进程会造成以下几个问题:(参考任玉刚老师的书):
1.静态成员和单例完全失效
解释:同一个类在不同进程中拥有不同的地址空间,虽然类名,类变量一样,但是分配的地址不一样,所以同一个类(指类名称)在不同的进程中是完全不同的类了。
2.线程同步机制失效
解释:不同地址空间,不同类,所以锁对象,锁全局类都不同了
3.Application会多次创建
解释:当指定一个组件跑在另外一个进程中时,Zygote会fork新的进程,当然会分配独立的虚拟机,整个过程就是启动了一个应用的过程。创建了一个新的Application对象。
总结:运行在同一个进程中的组件属于同一个虚拟机且同一个Application。多进程中不同进程的组件拥有不同的虚拟机,不 同的Application,不同的内存地址。
[2.3]多进程之间的通信
由于不同进程所拥有的地址是两块不同的地址空间,所以不能直接通过共享内存共享数据了。直接上Linux,Android的通信方式:
Linux常用跨进程通信方式:管道,信号量,共享内存,socket 。。。
Android常用跨进程通信方式:Intent ,共享文件,SharedPreferences,Binder,socket,基于Binder的Messenger.下面详细学习进程间的通信方式。