【问题标题】:android runtime.getruntime().exec() get process idandroid runtime.getruntime().exec() 获取进程id
【发布时间】:2012-10-14 21:09:17
【问题描述】:

如何通过 Android 应用程序获取使用 runtime.getruntime().exec() 启动的进程的进程 ID??

这就是问题所在。我从我的 UI 应用程序中使用 runtime.getruntime().exec() 启动了一个进程。如果我的 android UI 应用程序仍在运行,我可以使用 destroy 来终止进程.. 但是假设我使用主页或后退按钮退出应用程序,当我重新打开 ui 应用程序时,进程对象为空。那么我需要进程的PID来杀死它。

有没有更好的方法来做到这一点?

【问题讨论】:

    标签: android process pid


    【解决方案1】:

    Android java.lang.Process 实现是java.lang.ProcessManager$ProcessImpl,它有字段private final int pid;。可以从 Reflection 中获取:

    public static int getPid(Process p) {
        int pid = -1;
    
        try {
            Field f = p.getClass().getDeclaredField("pid");
            f.setAccessible(true);
            pid = f.getInt(p);
            f.setAccessible(false);
        } catch (Throwable e) {
            pid = -1;
        }
        return pid;
    }
    

    另一种方式 - 使用 toString:

        public String toString() {
            return "Process[pid=" + pid + "]";
        }
    

    您可以在没有反射的情况下解析输出并获取 pid。

    如此完整的方法:

    public static int getPid(Process p) {
        int pid = -1;
    
        try {
            Field f = p.getClass().getDeclaredField("pid");
            f.setAccessible(true);
            pid = f.getInt(p);
            f.setAccessible(false);
        } catch (Throwable ignored) {
            try {
                Matcher m = Pattern.compile("pid=(\\d+)").matcher(p.toString());
                pid = m.find() ? Integer.parseInt(m.group(1)) : -1;
            } catch (Throwable ignored2) {
                pid = -1;
            }
        }
        return pid;
    }
    

    【讨论】:

      【解决方案2】:

      你会使用 PID 来终止进程吗?如果是这样,您只需在您的 Process 实例上调用 destroy()。不需要PID。请注意,您需要使用 ProcessBuilder 而不是 getRuntime().exec() 来启动该进程,才能使其正常工作。

      如果您确实需要进程 ID,则可能需要使用 shell 脚本。 AFAIK 无法从 Java 获取 PID。

      编辑

      由于您需要在离开应用程序并返回到应用程序后保持对 Process 的句柄,因此一种解决方案是在生成 Process 的类中创建一个静态成员:

      private static Process myProcess;
      

      使用此成员将您通过调用start() 返回的Process 存储在您的ProcessBuilder 上。只要您的应用程序在内存中,静态成员就会一直存在——它不必是可见的。返回您的应用程序后应该可以终止该进程。如果系统碰巧杀死了您的应用程序以释放资源,那么您将无法终止子进程(如果它继续运行),但此解决方案应该适用于大多数情况。

      【讨论】:

      • 感谢您的帮助.. 静态工作现在...但是如果我的应用程序被杀死,我注定要失败 :)
      【解决方案3】:

      我已经使用 ActivityManager 完成了类似的操作,尽管在线文档中有针对它的警告...我也在作为系统应用运行,尽管我不确定这是否重要。

      ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
      int pid = 0;
      List<RunningAppProcessInfo> procInfo = am.getRunningAppProcesses();
      for (RunningAppProcessInfo proc : procInfo)
          if (proc.processName.indexOf("myApp") >= 0)
              pid = proc.pid;
      

      【讨论】:

        【解决方案4】:

        尝试以下方法:
        int p_Id = android.os.myPid(); For details

        【讨论】:

        • myPid() 返回您应用的 PID,而不是您使用 getRuntime().exec() 开始的进程。
        猜你喜欢
        • 2013-01-21
        • 1970-01-01
        • 2011-04-15
        • 1970-01-01
        • 1970-01-01
        • 2011-03-10
        • 2011-01-09
        • 2015-08-28
        • 2012-12-07
        相关资源
        最近更新 更多