为什么运行时在Android 4.0 / 4.0.3中被阻止?

时间:2012-03-27 09:17:55

标签: android memory runtime

我的UI仅在4.0。*中使用子句阻止:“Runtime.getRuntime()。exec(”cat proc / meminfo“);”。 以下代码有什么问题吗? 提前谢谢。

日志:

03-27 13:37:18.545: I/MyActivity(19730): ini().429: 1332826638549
03-27 13:37:18.545: I/MyActivity(19730): ini().434: 1332826638549
03-27 13:37:18.865: D/dalvikvm(19611): GC_CONCURRENT freed 389K, 6% free 9733K/10311K, paused 1ms+2ms

代码:

Log.i(getClass().getName(), "ini().434: " + System.currentTimeMillis());

try {
    Process process = Runtime.getRuntime().exec("cat proc/meminfo");//! hang here       
    Log.i(getClass().getName(), "ini().436: " + System.currentTimeMillis());
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));                            
    Log.i(getClass().getName(), "ini().438: " + System.currentTimeMillis());
    String str = bufferedReader.readLine();
    totleMemory = Long.parseLong(str.replaceAll("\\s+", "").replaceAll("[a-zA-Z]", "").replaceAll(":", ""));                            
    Log.i(getClass().getName(), "ini().441: " + System.currentTimeMillis());
    totleMemory *= 1024;
    } catch (Exception e) {
    }   

Log.i(getClass().getName(), "ini().446: " + System.currentTimeMillis());

3 个答案:

答案 0 :(得分:2)

非常感谢@Jared Burrows。 我读了一些文章,如“[当Runtime.exec()不会导航......] [1]”并将其替换为以下代码用于同样的目的:

//Process process = Runtime.getRuntime().exec("/system/bin/cat /proc/meminfo");
FileReader fr = new FileReader("cat /proc/meminfo");
BufferedReader reader = new BufferedReader(fr);
...more

我认为在UI Thread中调用此方法时存在一些潜在的问题。这里发布了stackoverflow中更多类似的线程:

Problem with Runtime.exec and Android

答案 1 :(得分:1)

我在Android 4.0.3中遇到同样的问题。 我发现使用gdb

在下面发生了死锁
    bionic/libc/bionic/pthread-atfork.c
    void __bionic_atfork_run_child()
    {
    ...
        pthread_mutex_unlock(&handler_mutex); <-- deadlock here

使用相同的代码在Android 4.2中进行测试是可以的。所以我使用git在仿生中找到解决方案。 我得到了解决方案并通过修补提交修复了此问题34e89c232dd5645fe3b5f9b40856d8e3e4cae57a

这是根本原因: atfork使用互斥锁handler_mutex来保护atfork_head。父级将调用__bionic_atfork_run_prepare()来锁定handler_mutex,并且需要父级和子级才能在fork之后解锁自己的handler_mutex副本。那时,hanlder_mutex的所有者被设置为父级。如果我们应用kernel_id修复,则子项的kernel_id将被设置为child的tid。

handler_mutex是递归锁,并且pthread_mutex_unlock(&amp; hander_mutex)将失败,因为互斥锁所有者是父级,而当前tid(__get_thread() - &gt; kernel_id)是子级,不与互斥锁所有者匹配。那时,handler_mutex处于锁定状态。如果孩子想要在之后分叉其他进程,那么它将尝试锁定handler_mutex,然后进行死锁。

答案 2 :(得分:0)

我刚刚在手机上打开终端应用程序,运行Android 4.0+并运行命令“cat / proc / meminfo”。我不允许该应用程序具有“su”或“root”权限,作为普通应用程序运行。命令成功完成。

因此,如果我可以使用手机上运行的应用程序通过命令行运行它,我相信我可以通过ADB shell进行操作,而且最有可能使用Java。

我之前在我的应用程序中使用过这段代码:

try 
    {
    Process process = Runtime.getRuntime().exec("/system/bin/cat /proc/meminfo");
    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
    int read;
    char[] buffer = new char[4096];
    StringBuffer output = new StringBuffer();
    while ((read = reader.read(buffer)) > 0) 
    {
        output.append(buffer, 0, read);
    }
    reader.close();
    process.waitFor();

    // wrap this in a method and return the string
    return output.toString();
} catch (Exception e) {
}

但是,当我尝试运行命令时,我没有正确的运行权限,我收到了错误“GC_CONCURRENT”。

此致