Runtime.exec() в Android зависает

Когда я пытаюсь выполнить внешний скрипт таким образом:

try {
    process = Runtime.getRuntime().exec(
        new String[] { "/system/bin/sh", "./myscript.sh" },
        null,
        "/data/mydir",
    );
} catch (IOException e) {
    Log.e(TAG, e.getMessage(), e);
} catch (SecurityException e) {
    Log.e(TAG, e.getMessage(), e);
}

Иногда скрипт выполняется, но чаще всего мое приложение зависает на пару секунд, пока Android не скажет, что мое приложение не отвечает и его нужно убить.

Мой вопрос в том, что может происходить. Скрипт запускается иногда, и исключение никакого не генерируется, он просто зависает. Я в недоумении, что происходит. Я использую Froyo (кажется, 2.2.1).

Спасибо!


person Albus Dumbledore    schedule 15.04.2011    source источник
comment
Хм, я думаю, что-то связано с потоками Android. Вы пробовали делать это в теме.   -  person Josnidhin    schedule 15.04.2011
comment
Ты так думаешь? Может, какой-то тупик происходит, не знаю. Вы правы, я дам ему отдельную ветку. :-)   -  person Albus Dumbledore    schedule 15.04.2011
comment
Ознакомьтесь с документом класса процесса developer.android.com/reference/java/lang/Process.html. Обзор кажется полезным и объясняет, почему он может блокироваться.   -  person Josnidhin    schedule 15.04.2011


Ответы (1)


В соответствии с документацией вы должны прочитать err и out поток процесса.

http://developer.android.com/reference/java/lang/Process.html

Я думаю, что что-то вроде следующего решит вашу проблему.

class Reader extends Thread
{
    InputStream is;

    Reader(InputStream is){
        this.is = is;
    }

    public void run()
    {
        try
        {
            InputStreamReader inStreamReader = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(inStreamReader);
            String line=null;
            while ( (line = br.readLine()) != null){
                // log here   
            }
        } catch (IOException ex){
            ex.printStackTrace();  
        }
    }
}

Используйте приведенный выше класс в своем коде следующим образом.

try {
    process = Runtime.getRuntime().exec(
        new String[] { "/system/bin/sh", "./myscript.sh" },
        null,
        "/data/mydir",
    );
    Reader err = new Reader(process.getErrorStream());
    Reader output = new Reader(process.getInputStream());

    err.start();
    outout.start();

} catch (IOException e) {
    Log.e(TAG, e.getMessage(), e);
} catch (SecurityException e) {
    Log.e(TAG, e.getMessage(), e);
} finally {
    process.destroy();
}
person Josnidhin    schedule 15.04.2011