2012-03-27 46 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,然後死鎖。

相關問題