有没有办法在Android中获取当前进程名称

我为我的特定活动设置了一个Android:process =“:XX”,以使其在单独的进程中运行。 但是,当新的活动/进程初始化时,它会调用我的Application:onCreate(),其中包含一些应用程序级别的初始化。

我正在考虑通过检查当前进程名称来避免重复初始化。

那么有没有可用的API?

谢谢。

Solutions Collecting From Web of "有没有办法在Android中获取当前进程名称"

如果我已经正确理解你的问题,你应该能够使用ActivityManager ,按照这个线程 。

完整的代码是

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

ActivityManager解决scheme包含一个鬼鬼祟祟的错误,特别是如果您从您的应用程序对象检查自己的进程名称。 有时,从getRunningAppProcesses返回的列表根本不包含您自己的过程,引发了一个特殊的存在问题。

我解决这个问题的方法是

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

编辑:请注意,这个解决scheme比通过ActivityManager快得多,但如果用户正在运行Xposed或类似的不起作用。 在这种情况下,您可能希望将ActivityManager解决scheme作为后备策略。

这是DavidBurström答案的更新。 这可以写得更加简洁:

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

好的,这是我的答案。

首先,获取当前进程的PID。 其次,列出所有正在运行的进程。 最后,如果它具有相同的PID,那么没关系,或者它是错误的。

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

我有更高效的方法,你不需要IPC来ActivityManagerService和轮询正在运行的进程,或读取文件。你可以从你的自定义应用程序类调用此方法;

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

(ActivityThread.main – > attach() – > IActivityManager.attachApplication – IPC – > ActivityManagerService – > ApplicationThread.bindApplication)ActivityManagerService已经将进程信息发送给ActivityThread。

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

当我们调用getProcessName时,它将最终传递给AppBindData对象。 所以我们可以轻松高效地获取当前进程名称;

ActivityThread类中有一个方法,您可以使用reflection来获取当前的processName。 你不需要任何循环或技巧。 性能是最好的比较其他解决scheme。 限制是你只能得到你自己的进程名称。 这不是什么大事,因为它涵盖了大部分使用情况。

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