Почему Runtime заблокирован в Android 4.0 / 4.0.3? - PullRequest
2 голосов
/ 27 марта 2012

Мой пользовательский интерфейс заблокирован только в 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 ]

2 голосов
/ 28 марта 2012

Спасибо вам все равно, @ Джаред Барроуз. Я прочитал статью типа «[Когда 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

Я предполагаю, что существует потенциальная проблема, когда этот метод вызывается в потоке пользовательского интерфейса. Более похожая тема в stackoverflow была опубликована здесь:

Проблема с Runtime.exec и Android

1 голос
/ 05 июня 2013

У меня такая же проблема в 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, и потребуется, чтобы родитель и потомок разблокировали свою собственную копию handler_mutex после fork. В это время владелец hanlder_mutex устанавливается в качестве родителя. Если мы применим исправление kernel_id, то дочерний kernel_id будет установлен как дочерний tid.

handler_mutex является рекурсивной блокировкой, и pthread_mutex_unlock (& ​​hander_mutex) завершится ошибкой, поскольку владелец мьютекса является родительским, а текущий tid (__get_thread () -> kernel_id) является дочерним, а не совпадает с владельцем мьютекса. В это время handler_mutex остается в состоянии блокировки. Если дочерний элемент хочет после этого обработать другой процесс, он попытается заблокировать handler_mutex, а затем заблокируется.

0 голосов
/ 28 марта 2012

Я только что открыл терминальное приложение на своем телефоне под управлением Android 4.0+ и запустил вашу команду "cat / proc / meminfo". Я не позволял приложению иметь права «su» или «root», работающие как обычное приложение. Команда выполнена успешно.

Так что, если я могу запустить его через командную строку с помощью приложения, работающего на телефоне, я уверен, что смогу сделать это через оболочку ADB и, скорее всего, в 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".

С уважением,

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...