一、在 APP 中启动多个进程(最简单实现)
1、Service
public class MyServiceA extends Service {
public static final String TAG = MyServiceA.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "MyServiceA 启动");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
public class MyServiceB extends Service {
public static final String TAG = MyServiceB.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "MyServiceB 启动");
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
2、AndroidManifest
- AndroidManifest.xml
<service
android:name=".service.MyServiceA"
android:exported="false"
android:process=":MyServiceA" />
<service
android:name=".service.MyServiceB"
android:exported="false"
android:process=":MyServiceB" />
通过配置 process 来配置多进程,如果不配置 process,默认在主进程运行
process 配置为 :MyServiceA 表示进程名为 【包名】:MyServiceA
- 注:不建议将process 配置为 .MyServiceA,这样进程名就会变为 【包名】.MyServiceA
3、Activity Code
startService(new Intent(this, MyServiceA.class));
startService(new Intent(this, MyServiceB.class));
new Handler().postDelayed(() -> CommonTool.printAllProcesses(this.getApplicationContext()), 5 * 1000);
# 输出结果
MyServiceA 启动
MyServiceB 启动
总进程数: 3
进程名: com.my.androidadvance, PID: 29146, UID: 10246
进程名: com.my.androidadvance:MyServiceB, PID: 29271, UID: 10246
进程名: com.my.androidadvance:MyServiceA, PID: 29263, UID: 10246
二、查看进程
1、通过 ps 命令查看进程
ps -ef
ps -ef | grep 【包名】
2、通过 ActivityManager 查看进程
- 通过 ActivityManager 查看进程,但是,只能查看调用者自身的进程
public static void printAllProcesses(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = activityManager.getRunningAppProcesses();
if (runningAppProcesses == null) {
Log.e("printAllProcesses", "进程列表为 null");
return;
}
Log.i("ProcessCheck", "总进程数: " + runningAppProcesses.size());
for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : runningAppProcesses) {
Log.i("printAllProcesses",
"进程名: " + runningAppProcessInfo.processName + ", " +
"PID: " + runningAppProcessInfo.pid + ", " +
"UID: " + runningAppProcessInfo.uid);
}
}
CommonTool.printAllProcesses(this)
// 或者
CommonTool.printAllProcesses(this.getApplicationContext())
三、多进程下 Application 多次创建
1、基本介绍
- 每个进程都会单独初始化一个 Application 实例,每个进程启动时都会调用一次 onCreate 方法,需要根据进程名做不同初始化
2、演示
public class MyApplication extends Application {
public static final String TAG = MyApplication.class.getSimpleName();
public MyApplication() {
Log.i(TAG, "MyApplication 构造函数被调用");
}
@Override
public void onCreate() {
super.onCreate();
String processName = getProcessName();
Log.i(TAG, "onCreate, processName: " + processName);
}
}
# 输出结果
MyApplication 构造函数被调用
onCreate, processName: com.my.androidadvance
MyApplication 构造函数被调用
onCreate, processName: com.my.androidadvance:MyServiceA
MyServiceA 启动
MyApplication 构造函数被调用
onCreate, processName: com.my.androidadvance:MyServiceB
MyServiceB 启动
总进程数: 3
进程名: com.my.androidadvance, PID: 30763, UID: 10246
进程名: com.my.androidadvance:MyServiceB, PID: 30814, UID: 10246
进程名: com.my.androidadvance:MyServiceA, PID: 30808, UID: 10246
四、多进程下单例模式失效
1、Singleton
- SimpleSingleton.java
public class SimpleSingleton {
public static final String TAG = SimpleSingleton.class.getSimpleName();
private String data = "no data";
private static SimpleSingleton simpleSingleton = new SimpleSingleton();
private SimpleSingleton() {
Log.d(TAG, "单例创建,进程 ID:" + android.os.Process.myPid());
}
public static SimpleSingleton getInstance() {
return simpleSingleton;
}
public void setData(String data) {
this.data = data;
Log.d(TAG, "进程 " + android.os.Process.myPid() + " 设置数据:" + data);
}
public String getData() {
Log.d(TAG, "进程 " + android.os.Process.myPid() + " 读取数据:" + data);
return data;
}
}
2、Service
public class MyServiceA extends Service {
public static final String TAG = MyServiceA.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "MyServiceA 启动");
new Handler(Looper.getMainLooper()).postDelayed(() -> {
SimpleSingleton simpleSingleton = SimpleSingleton.getInstance();
String data = simpleSingleton.getData();
Log.i(TAG, "MyServiceA 从 SimpleSingleton 读取数据:" + data);
}, 9 * 1000);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
public class MyServiceB extends Service {
public static final String TAG = MyServiceB.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "MyServiceB 启动");
new Handler(Looper.getMainLooper()).postDelayed(() -> {
SimpleSingleton simpleSingleton = SimpleSingleton.getInstance();
String data = simpleSingleton.getData();
Log.i(TAG, "MyServiceB 从 SimpleSingleton 读取数据:" + data);
}, 9 * 1000);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
3、Activity Code
startService(new Intent(this, MyServiceA.class));
startService(new Intent(this, MyServiceB.class));
new Handler().postDelayed(() -> CommonTool.printAllProcesses(this.getApplicationContext()), 3 * 1000);
new Handler().postDelayed(() -> {
SimpleSingleton simpleSingleton = SimpleSingleton.getInstance();
simpleSingleton.setData("test content");
Log.i(TAG, "主进程向 SimpleSingleton 写入数据");
}, 6 * 1000);
# 输出结果
MyServiceA 启动
MyServiceB 启动
总进程数: 3
进程名: com.my.androidadvance, PID: 10962, UID: 10246
进程名: com.my.androidadvance:MyServiceB, PID: 11015, UID: 10246
进程名: com.my.androidadvance:MyServiceA, PID: 11009, UID: 10246
单例创建,进程 ID:10962
进程 10962 设置数据:test content
主进程向 SimpleSingleton 写入数据
单例创建,进程 ID:11009
进程 11009 读取数据:no data
MyServiceA 从 SimpleSingleton 读取数据:no data
单例创建,进程 ID:11015
进程 11015 读取数据:no data
MyServiceB 从 SimpleSingleton 读取数据:no data



