import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.lang.reflect.Method;
import java.util.List;
public class ProcessHelper {
/**
* 当前进程名
*/
private static String currentProcessName;
/**
* @return 当前进程名
*/
@Nullable
public static String getCurrentProcessName(@NonNull Context context) {
if (TextUtils.isEmpty(currentProcessName)) {
synchronized (ProcessHelper.class) {
if (TextUtils.isEmpty(currentProcessName)) {
//1)通过Application的API获取当前进程名
currentProcessName = getCurrentProcessNameByApplication();
if (TextUtils.isEmpty(currentProcessName)) {
//2)通过反射ActivityThread获取当前进程名
currentProcessName = getCurrentProcessNameByActivityThread();
if (TextUtils.isEmpty(currentProcessName)) {
//3)通过ActivityManager获取当前进程名
currentProcessName = getCurrentProcessNameByActivityManager(context);
}
}
}
}
}
return currentProcessName;
}
/**
* 通过Application新的API获取进程名,无需反射,无需IPC,效率最高。
*/
private static String getCurrentProcessNameByApplication() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
return Application.getProcessName();
}
return null;
}
/**
* 通过反射ActivityThread获取进程名,避免了ipc
*/
private static String getCurrentProcessNameByActivityThread() {
String processName = null;
try {
@SuppressLint("PrivateApi") final Class<?> clz = Class.forName("android.app.ActivityThread", false, Application.class.getClassLoader());
@SuppressLint("DiscouragedPrivateApi") final Method m = clz.getDeclaredMethod("currentProcessName");
m.setAccessible(true);
final Object name = m.invoke(null);
if (name instanceof String) {
processName = (String) name;
}
} catch (Throwable e) {
e.printStackTrace();
}
return processName;
}
/**
* 通过ActivityManager 获取进程名,需要IPC通信
*/
private static String getCurrentProcessNameByActivityManager(@NonNull Context context) {
final int pid = android.os.Process.myPid();
final ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (null != am) {
final List<ActivityManager.RunningAppProcessInfo> runningAppList = am.getRunningAppProcesses();
if (null != runningAppList) {
for (ActivityManager.RunningAppProcessInfo processInfo : runningAppList) {
if (processInfo.pid == pid) {
return processInfo.processName;
}
}
}
}
return null;
}
}