2012-03-27 52 views
2

我的用户界面仅在4.0中被阻止*使用子句:“Runtime.getRuntime().exec(”cat proc/meminfo“);”。 下面的代码有什么问题吗? 在此先感谢。为什么运行时在Android 4.0/4.0.3中被阻止?

登录:

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

回答

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”:

我以前用这个代码在我的应用程序。

Regards,

+0

MasterJB,谢谢你们一样。 – thecr0w 2012-04-05 03:10:46

+0

顺便说一句,你是否同意这种说法:因为有三个流(stdin,stdout,stderr),我们可以通过1.getErrorStream()获取2。getInputStream()3.getOutputStream(),并且只有在错误流完成后才会获得输入流,如果发生某些意外错误。或者会有阻塞,是这样吗? – thecr0w 2012-04-05 03:21:01

+0

我不确定我是否只为我的应用程序使用了InputStream。你仍然有错误,或者你在做更多的研究吗? – 2012-04-05 03:23:31

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.Much被称为计算器更类似于螺纹的问题是张贴在这里:

Problem with Runtime.exec and Android

+0

非常感谢:P – 2012-04-17 18:49:17

1

我在安卓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将被设置为孩子的tid。

的handler_mutex是一个递归锁,并调用pthread_mutex_unlock(& hander_mutex)将失败,因为互斥的所有者是父,而目前的TID(__get_thread() - > kernel_id)是孩子,不是互斥的所有者匹配。那时,handler_mutex保持锁定状态。如果孩子想在fork之后fork其他进程,那么它会尝试锁定handler_mutex,然后死锁。

相关问题