簡體   English   中英

Android-交互式外殼程序(Runtime.getRuntime()。exec())

[英]Android - Interactive shell (Runtime.getRuntime().exec())

如何在Android上運行交互式Shell? (根設備)

我需要接下來的步驟:

1-執行外殼程序(onCreate)

Process p = Runtime.getRuntime().exec(String[]{"su","-c","sh"});

2-獲取輸出(onCreate)

BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream));
//dos is a field (a class attribute)
dos = new DataOutputStream(p.getOutputStream());
new Thread(new Runnable() {

    @Override
    public void run() {
         String l;
         //wait the console output and write it
         while((l = br.readLine()) != null) {
              Log.v("info", l);
         }
    }
}).start();

3-執行命令(按鈕-> onClick())

cmd("wpa_cli");

cmd方法是:

public void cmd(String cmd) {
   dos.writeBytes(cmd + "\n");
   dos.flush();
}

日志從不顯示控制台輸出。

下一步:

4-獲取wpa_cli子命令的輸出(另一個Button-> onClick())

cmd("help");

應該顯示wpa_cli幫助,但不起作用。
如果我多次按該按鈕,則顯示的輸出不完整(幫助)

創建活動並保持活動狀態以進行交互時,初始化過程的正確方法是什么?

謝謝。

發布數據
我替換了Log.v("info", l);

fos.write(l);
Message msg = handlerTest.obtainMessage();
msg.obj = l;
handlerTest.sendMessage(msg);

fos-> FileOutputStream對象

Handler handlerTest = new Handler() {
    @Override
    handleMessage(Message msg) {
       if (msg != null) {
         //alert... (String)msg.obj;
       }
    }
}; 

並且僅顯示直接命令中的警報,例如help 命令status僅在流關閉時起作用。 (在執行cmd("quit");cmd("exit");

我不明白 標准輸出不止一個? 我可以在不關閉流的情況下與輸出交互嗎?

使用adb shell我讀取了輸出文件(在關閉流之后創建),並且文件已完成。

PostData2:

問題是緩沖區。 在二進制文件(已執行)輸出和Java進程之間,我可以不使用本機I / O禁用緩沖區嗎? Android Terminal Emulator工作正常,是否正在使用NIO?

由OP解決。

在不使用Android中(coreutils的) stdbuf工具的情況下,我找到了下一個解決方案:

我正在使用兩個名為process1和process2的進程:都-> new ProcessBuilder(new String[]{"su", "-c", "sh"}).start();

在第一個過程中,我運行wpa_cli

dos1.write("wpa_cli".getBytes());
dos1.flush();

在線程中,我等待5秒鍾,然后在第二個進程中運行wpa_cli。

dos2.write("wpa_cli".getBytes());
dos2.flush();

要從wpa_cli獲取輸出,必須通過quit將其關閉

dos1.write("quit".getBytes());
dos1.flush();

適用於這兩個進程的主線程:

new Thread(new Runnable() {
                @Override
                public void run() {
                    boolean firstProcess = true;
                    while (follow) {
                        try {
                            Thread.sleep(5000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (follow) {
                            if (firstProcess) {
                                cmd("wpa_cli", dos2);
                                cmd("quit", dos1);
                            } else {
                                cmd("wpa_cli", dos1);
                                cmd("quit", dos2);
                            }
                            firstProcess = !firstProcess;
                        }
                    }
                }
            }).start();

重要說明 :這兩個過程都具有此功能(在創建過程時):

new Thread(new Runnable() {
                    @Override
                    public void run() {
                        BufferedReader br = new BufferedReader(new InputStreamReader(process1.getInputStream()));
                        String l;
                        try {
                            Message msg;
                            while ((l = br.readLine()) != null) {
                                msg = handlerStdout.obtainMessage();
                                msg.obj = l;
                                handlerStdout.sendMessage(msg);
                            }

                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();

處理程序handlerStdout完成了所需的工作。 它每5秒接收一次wpa_cli的輸出:輸出交替來自process1和process2


另一種解決方案是為Android編譯coreutils或stdbuf 或從http://forum.xda-developers.com/showthread.php?t=2613243安裝編譯的coreutils(對我stdbuflibstdbuf.so stdbuf因為libstdbuf.so

使用stdbuf -oL wpa_cli ,輸出不會被緩沖(緩沖一行)。 沒有它,輸出將被緩沖(4k)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM