通过 ActivityManager 获取进程名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public static String getCurrentProcessNameByActivityManager(@NonNull Context context) { final int pid = 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; } |
缺点:
- am.getRunningAppProcesses()需要跨进程通信,效率不高
- ActivityManager.getRunningAppProcesses() 有可能调用失败,虽然概率不高但是当用户数量达到一定级别还是有概率失败的
- Application.getProcessName() 只能Api28 以上的系统调用
最优解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
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; } } |