Android获取当前进程的名称

通过 ActivityManager 获取进程名

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;
}

缺点:

  1. am.getRunningAppProcesses()需要跨进程通信,效率不高
  2. ActivityManager.getRunningAppProcesses() 有可能调用失败,虽然概率不高但是当用户数量达到一定级别还是有概率失败的
  3. Application.getProcessName() 只能Api28 以上的系统调用

最优解:

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;
    }
}

参考链接


android 获取当前进程的名称