1、概念
1.1 进程
- 程序运行的基本单元。
- 系统资源分配和调度的基本单位。
- 有自己独立的地址空间。
- 多个进程可并发执行。
1.2 线程
- 程序执行的最小单位。
- CPU调度和分派的基本单位。
- 没有独立的地址空间,多个线程共享地址空间。
- 多个线程可并发执行,某一个线程可以创建和撤销另外的线程。
1.3 进程和线程的区别
- 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。
- 资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、CPU等,但是进程之间的资源是独立的。
- 一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以使用多进程可以保证其他模块的正常运行。
- 进程切换时,消耗的资源大,效率不高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程。
- 执行过程:每个独立的进程程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
- 都可以并发执行。
- 一个程序至少有一个进程,一个进程至少有一个线程。
可以将系统看成一个工厂,进程就是车间,多进程就是多个车间,线程就是流水线,多进程就是多个车间,多线程就是多个流水线。
2、Android中的进程
2.1 进程
当应用程序组件启动并且该应用程序没有任何其他组件在运行时,Android 系统会为该应用程序启动一个新的 Linux 进程,并使用单个执行线程。 默认情况下,同一应用程序的所有组件都在同一进程和线程(称为"主"线程)中运行。
2.2 进程的等级(生命周期)
2.2.1 前台进程(Foreground process)
它表明用户正在与该进程进行交互操作优先级是最高的。Android系统-依据下面的条件来将一个进程标记为前台进程:
- 有一个Activity且正在执行**onResume()**方法(用户正在与其交互)。
- 有一个Service且正在执行(onCreate()、onStart()、onDestroy())之一的方法。
- 有一个BroadcastReceiver且正在执行 onReceive() 方法。
2.2.2 可见进程(Visible process)
它表明虽然该进程没有持有任何前台组件,但是它还是能够影响到用户看得到的界面。android系统依据下面的条件将一个进程标记为可见进程:
- 有一个Activity且它不在交互,但仍可见(其 onPause() 方法已被调用)。例如,当一个activity启动了一个dialog,这个activity就被对话框挡在后面。
- 有一个**Service正在执行Service.startForeground()**的方法。
- 托管系统用于用户知道的特定功能的服务,例如动态壁纸、输入法服务等。
2.2.3 服务进程(Service process)
持有已使用 startService() 方法启动的Service。 虽然这些进程对用户来说并不直接可见,但它们一般都在做用户关心的事情(如后台网络数据上传或下载)
2.2.4 缓存进程(Cached process)
缓存进程是当前不需要的进程,因此当其他地方需要内存等资源时,系统可以根据需要随意终止它。
- 持有一个或多个不可见Activity(调用了onStop()方法)。通常情况下都会有很多后台进程,当内存不足的时候,在所有的后台进程里面,会按照LRU(最近使用)规则,优先回收最长时间没有使用过的进程。
在决定如何对流程进行分类时,系统将根据在流程中当前活动的所有组件中找到的最重要的级别来做出决定。
进程的优先级也可以基于进程对它的其他依赖性而增加。
2.3 多进程
默认情况下,同一应用程序的所有组件都在同一进程中运行,大多数应用程序不应更改这一点。但是,如果你发现需要控制某个组件属于哪个进程,则可以在 < application> 中进行。
每种类型的组件元素 (< activity >、< service>、< receiver> 和 < provider>) 的清单条目都支持 android:process 属性,该属性可以指定该组件应在其中运行的进程。
< application> 元素还支持 android:process 属性,以设置适用于所有组件的默认值。
Android 的一个不同寻常的基本特性是应用程序进程的生命周期不受应用程序本身直接控制。相反,它是由系统通过系统知道正在运行的应用程序部分的组合、这些东西对用户的重要性以及系统中可用的总内存量来确定的。
默认进程就是主进程。其他进程一般来说都是子进程。
2.3.1 多进程产生多个Application
如果注册的四大组件中的任意一个组件时用到了多进程,运行该组件时,都会创建一个新的Application对象。对于多进程重复创建Application这种情况,只需要在该类中对当前进程加以判断即可。
com.scc.demo(12095):com.scc.demo进程名;12095进程id
代码实现:AndroidMainfest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.scc.demo"> <application android:name=".SccApp" ... android:theme="@style/Theme.Demo"> <activity android:name=".actvitiy.MainActivity" > ... </activity> <activity android:name=".actvitiy.TouchActivity" android:process="com.scc.touch.wudi"/> <activity android:name=".actvitiy.ViewActivity" android:process=":view"/> ... </application> </manifest>
根据默认进程名和当前进程名比较是否进行初始化。
public class SccApp extends Application { @RequiresApi(api = Build.VERSION_CODES.P) @Override public void onCreate() { super.onCreate(); String name = getProcessName(); MLog.e("ProcessName:"+name); getProcessName("com.scc.demo"); } public void getProcessName(String processName){ ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); List<ActivityManager.RunningAppProcessInfo> processInfos = activityManager.getRunningAppProcesses(); if(processInfos!=null) { for(ActivityManager.RunningAppProcessInfo processInfo:processInfos){ MLog.e(processInfo.processName); if(processName == processInfo.processName){ init(); } } } } //初始化 private void init(){ CrashReport.initCrashReport(getApplicationContext(), "70594a1ff8", false); } }
2.4 进程间通信
- Bundle
- 文件共享
- AIDL
- Messenger
- Content Provider
- Socket