2014-11-09 4 views
2

Я разрабатываю приложение, выполняющее несколько команд оболочки в разное время. Я использую следующий метод:Выполнение нескольких команд корневой оболочки в Android

public void RunAsRoot(String[] cmds){ 
     Process p = Runtime.getRuntime().exec("su"); 
     DataOutputStream os = new DataOutputStream(p.getOutputStream());    
     for (String tmpCmd : cmds) { 
       os.writeBytes(tmpCmd+"\n"); 
     }   
     os.writeBytes("exit\n"); 
     os.flush(); 
} 

Этот метод отлично работает, но он всегда открывать новую оболочку каждый раз, когда мне нужно, чтобы назвать его, так что он отображает раздражающий тост «Применение было предоставлено для корневого разрешения ». Я думаю, что это потому, что он всегда открывает и закрывает новую оболочку с доступом SU. Мой вопрос: есть ли способ оставить оболочку SU всегда открытой, чтобы я мог запускать свои команды, когда это необходимо, без получения тоста SU?

+0

Проверьте https://github.com/Chainfire/libsuperuser или https://github.com/Stericson/RootTools –

+0

Im фактически использует libsuperuser от chainfire, но Shell.SU.run всегда открывает новую оболочку! – iGio90

ответ

0

Так что это может быть немного поздно, но в случае, если вы все еще ищете решение: Просто объявить

private Process p = Runtime.getRuntime().exec("su"); 

глобально в своем классе. Это должно соответствовать вашим потребностям. На самом деле вы можете создать процесс в onResume() и destroy() снова в onPause().

@Override 
onResume() { 
    if(//check for root) { 
    try { 
     this.p = Runtime.getRuntime().exec("su"); 
     } 
    catch(IOException e) { 
     // Exception handling goes here 
     } 
    } 
    //set up everything else 
} 

@Override 
onPause() { 
    this.p.destroy(); 
} 

BTW: Я вижу серьезную утечку памяти в указанном выше способе: Открывает разнообразные процессы SU, но никогда не destroy() их снова. В зависимости от того, как часто вы вызываете этот метод, в ОЗУ будет все больше и больше СУ-процессов, пока ваше приложение не будет закрыто.

Так

public void runAsRoot(String[] cmds){ try { Process p = Runtime.getRuntime().exec("su"); } catch(IOException e) { // Exception handling goes here } DataOutputStream os = new DataOutputStream(p.getOutputStream());
for (String tmpCmd : cmds) { os.writeBytes(tmpCmd+"\n"); }
os.writeBytes("exit\n"); os.flush(); p.destroy(); }

бы хорошо здесь. Я также спрашиваю себя, можете ли вы скомпилировать свой подход. Обычно Runtime.getRuntime().exec(); должен быть окружен try/catch.

Смежные вопросы