Is there a way to get current process name in Android

Android

Android Problem Overview


I set an Android:process=":XX" for my particular activity to make it run in a separate process. However when the new activity/process init, it will call my Application:onCreate() which contains some application level initialization.

I'm thinking of avoiding duplication initialization by checking current process name.

So is there an API available?

Thanks.

Android Solutions


Solution 1 - Android

Full code is

	String currentProcName = "";
	int pid = android.os.Process.myPid();
	ActivityManager manager = (ActivityManager) this.getSystemService(Context.ACTIVITY_SERVICE);
	for (RunningAppProcessInfo processInfo : manager.getRunningAppProcesses())
	{
		if (processInfo.pid == pid)
		{
			currentProcName = processInfo.processName;
			return;
		}
	}

Solution 2 - Android

The ActivityManager solution contains a sneaky bug, particularly if you check your own process name from your Application object. Sometimes, the list returned from getRunningAppProcesses simply doesn't contain your own process, raising a peculiar existential issue.

The way I solve this is

	BufferedReader cmdlineReader = null;
	try {
		cmdlineReader = new BufferedReader(new InputStreamReader(
			new FileInputStream(
				"/proc/" + android.os.Process.myPid() + "/cmdline"),
			"iso-8859-1"));
		int c;
		StringBuilder processName = new StringBuilder();
		while ((c = cmdlineReader.read()) > 0) {
			processName.append((char) c);
		}
		return processName.toString();
	} finally {
		if (cmdlineReader != null) {
			cmdlineReader.close();
		}
	}

EDIT: Please notice that this solution is much faster than going through the ActivityManager but does not work if the user is running Xposed or similar. In that case you might want to do the ActivityManager solution as a fallback strategy.

Solution 3 - Android

Get it from ActivityThread

In API 28+, you can call Application.getProcessName(), which is just a public wrapper around ActivityThread.currentProcessName().

On older platforms, just call ActivityThread.currentProcessName() directly.

Note that prior to API 18, the method was incorrectly called ActivityThread.currentPackageName() but still in fact returned the process name.

Example code
public static String getProcessName() {
    if (Build.VERSION.SDK_INT >= 28)
        return Application.getProcessName();

    // Using the same technique as Application.getProcessName() for older devices
    // Using reflection since ActivityThread is an internal API

    try {
        @SuppressLint("PrivateApi")
        Class<?> activityThread = Class.forName("android.app.ActivityThread");

        // Before API 18, the method was incorrectly named "currentPackageName", but it still returned the process name
        // See https://github.com/aosp-mirror/platform_frameworks_base/commit/b57a50bd16ce25db441da5c1b63d48721bb90687
        String methodName = Build.VERSION.SDK_INT >= 18 ? "currentProcessName" : "currentPackageName";

        Method getProcessName = activityThread.getDeclaredMethod(methodName);
        return (String) getProcessName.invoke(null);
    } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
    } catch (NoSuchMethodException e) {
        throw new RuntimeException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimeException(e);
    } catch (InvocationTargetException e) {
        throw new RuntimeException(e);
    }
}
Compatibility

Tested and working on

  • Official emulator

    • 16
    • 17
    • 18
    • 19
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • Q beta 1
  • Real devices

    • Motorola Moto G5 Plus running Android 8.1.0
    • Samsung Galaxy S5 running Android 6.0.1
    • Sony Xperia M running stock Android 7.1.1
    • Sony Xperia M running Sony Android 4.1.2

Solution 4 - Android

This is an update to David Burström's answer. This can be written far more concisely as:

public String get() {
  final File cmdline = new File("/proc/" + android.os.Process.myPid() + "/cmdline");
  try (BufferedReader reader = new BufferedReader(new FileReader(cmdline))) {
    return reader.readLine();
  } catch (IOException e) {
    throw new RuntimeException(e);
  }
}

Solution 5 - Android

I have more efficient method, you don't need IPC to ActivityManagerService and poll the Running process, or read the file.You can call this method from your custom Application class;

 private String getProcessName(Application app) {
    String processName = null;
    try {
        Field loadedApkField = app.getClass().getField("mLoadedApk");
        loadedApkField.setAccessible(true);
        Object loadedApk = loadedApkField.get(app);

        Field activityThreadField = loadedApk.getClass().getDeclaredField("mActivityThread");
        activityThreadField.setAccessible(true);
        Object activityThread = activityThreadField.get(loadedApk);

        Method getProcessName = activityThread.getClass().getDeclaredMethod("getProcessName", null);
        processName = (String) getProcessName.invoke(activityThread, null);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return processName;
}

ActivityManagerService is already send the process infor to ActivityThread when process is start.(ActivityThread.main-->attach()-->IActivityManager.attachApplication--IPC-->ActivityManagerService-->ApplicationThread.bindApplication)

ApplicationThread:
public final void bindApplication(String processName,***) {
    //***
    AppBindData data = new AppBindData();
    data.processName = processName;
    //**
}

When we called getProcessName, it will finally deliver to AppBindData object. So we can easily and efficient get current process name;

Solution 6 - Android

To wrap up different approaches of getting process name using Kotlin:

Based on the https://stackoverflow.com/a/21389402/3256989 (/proc/pid/cmdline):

    fun getProcessName(): String? =
        try {
            FileInputStream("/proc/${Process.myPid()}/cmdline")
                .buffered()
                .readBytes()
                .filter { it > 0 }
                .toByteArray()
                .inputStream()
                .reader(Charsets.ISO_8859_1)
                .use { it.readText() }
        } catch (e: Throwable) {
            null
        }

Based on https://stackoverflow.com/a/55549556/3256989 (from SDK v.28 (Android P)):

  fun getProcessName(): String? = 
    if (VERSION.SDK_INT >= VERSION_CODES.P) Application.getProcessName() else null

Based on https://stackoverflow.com/a/45960344/3256989 (reflection):

    fun getProcessName(): String? =
        try {
            val loadedApkField = application.javaClass.getField("mLoadedApk")
            loadedApkField.isAccessible = true
            val loadedApk = loadedApkField.get(application)

            val activityThreadField = loadedApk.javaClass.getDeclaredField("mActivityThread")
            activityThreadField.isAccessible = true
            val activityThread = activityThreadField.get(loadedApk)

            val getProcessName = activityThread.javaClass.getDeclaredMethod("getProcessName")
            getProcessName.invoke(activityThread) as String
        } catch (e: Throwable) {
            null
        }

Based on https://stackoverflow.com/a/19632382/3256989 (ActivityManager):

    fun getProcessName(): String? {
        val pid = Process.myPid()
        val manager = appContext.getSystemService(Context.ACTIVITY_SERVICE) as? ActivityManager
        return manager?.runningAppProcesses?.filterNotNull()?.firstOrNull { it.pid == pid }?.processName
    }

Solution 7 - Android

First, get the current process pid. Second, list all processes of running. Finally, if it has equal pid, it's ok, or it's false.

public static String getProcessName(Context context) {
    int pid = android.os.Process.myPid();
    ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> infos = manager.getRunningAppProcesses();
    if (infos != null) {
        for (ActivityManager.RunningAppProcessInfo processInfo : infos) {
            if (processInfo.pid == pid) {
                return processInfo.processName;
            }
        }
    }
    return null;
}

Solution 8 - Android

Since Android Pie (SDK v28), there is actually an official method for this in the Application class:

public static String getProcessName ()

See the docs

Solution 9 - Android

If I've understood your question correctly, you should be able to use ActivityManager, as per this thread.

Solution 10 - Android

There is a method in ActivityThread class, You may use reflection to get the current processName. You don't need any loop or tricks. The performance is best compares to other solution. The limitation is you can only get your own process name. It's not a big deal since it covers most usage cases.

    val activityThreadClass = XposedHelpers.findClass("android.app.ActivityThread", param.classLoader)
    val activityThread = XposedHelpers.callStaticMethod(activityThreadClass, "currentActivityThread")
    val processName = XposedHelpers.callStaticMethod(activityThreadClass, "currentProcessName")

Solution 11 - Android

The main process's father process should be zygote, this should be the accurate solution

  1. first judge the process's name from /proc/pid/cmdline which should equal to package name
  2. judge the process's father whether Zygote(why do this? because some APP have different processes with same name)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRick LiView Question on Stackoverflow
Solution 1 - AndroidRick LiView Answer on Stackoverflow
Solution 2 - AndroidDavid BurströmView Answer on Stackoverflow
Solution 3 - AndroidSamView Answer on Stackoverflow
Solution 4 - AndroidMark RenoufView Answer on Stackoverflow
Solution 5 - AndroidSnow AlbertView Answer on Stackoverflow
Solution 6 - AndroidultraonView Answer on Stackoverflow
Solution 7 - AndroidC.L. WangView Answer on Stackoverflow
Solution 8 - AndroidJohnson_145View Answer on Stackoverflow
Solution 9 - AndroidRichard HorrocksView Answer on Stackoverflow
Solution 10 - AndroidwukongView Answer on Stackoverflow
Solution 11 - Androiduser10318067View Answer on Stackoverflow