Android通過Runtime.getRuntime().exec實現Ping和Traceroute命令時readLine阻塞問題解決
在PC上呼叫cmd,進行一些常用的命令操作,在Android上的是通過Runtime.getRuntime().exec來執行底層Linux下的程式或指令碼(bat)。
首先連線上真機,電腦開啟CMD,輸入adb-shell,確保你要進行的指令碼語言是可以執行的。(比如常見的ping命令)
但是深入一下,發現使用ping命令,並附加一些引數,我們設定 -w 5 了,希望5秒鐘如果沒有ping通,可以有返回,可是像如下常規的操作,貌似ping下的附加引數是不會起作用的,也就是說在cmd下,我希望ping後5秒沒有收到包就返回,但是在android下執行就不會有效果:
這種常規的操作,如果執行一條Ping命令,當在某個ip下卡住ping不通時,就有問題了,會發現程式碼一直會阻塞在br.readLine()的地方,任何辦法都不好解決,網上說的把操作放在另外一個Thread裡進行,只是解決了process.waiFor()的阻塞問題。其實也解決不了當進行ping不通時readline阻塞的問題,在ping命令的操作下使用readline並不像讀取一個檔案,當遇到換行時會結束,ping不通,只能一直阻塞著,除非在外部進行close等操作。Process process = null; InputStream instream = null; BufferedReader bufferReader = null; try { process = Runtime.getRuntime().exec(command); instream = process.getInputStream(); bufferReader = new BufferedReader(new InputStreamReader(instream, "GBK")); String readline; while ((readline = bufferReader.readLine()) != null) { results.add(readline); // Log.i(TAG, "execute command result : " + readline); } int status = process.waitFor(); Log.i(TAG, "execute command :" + command + ", status : " + status); } catch (IOException e) { Log.e(TAG, e.getMessage()); } catch (InterruptedException e) { Log.e(TAG, e.getMessage()); }
結合國內外論壇,終於找到一個辦法,我寫成了一個方法類,供大家參考(可直接呼叫):
package com.vixtel.netvista.gdcmcc.utils; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.Locale; import android.util.Log; /*** * 執行命令列工具類 * * @author yangxiaolong 2014-04-30 * */ public class CommandUtil { public static final String TAG = CommandUtil.class.getSimpleName(); public static final String COMMAND_SH = "sh"; public static final String COMMAND_LINE_END = "\n"; public static final String COMMAND_EXIT = "exit\n"; private static final boolean ISDEBUG = true; /** * 執行單條命令 * * @param command * @return */ public static List<String> execute(String command) { return execute(new String[] { command }); } /** * 可執行多行命令(bat) * * @param commands * @return */ public static List<String> execute(String[] commands) { List<String> results = new ArrayList<String>(); int status = -1; if (commands == null || commands.length == 0) { return null; } debug("execute command start : " + commands); Process process = null; BufferedReader successReader = null; BufferedReader errorReader = null; StringBuilder errorMsg = null; DataOutputStream dos = null; try { // TODO process = Runtime.getRuntime().exec(COMMAND_SH); dos = new DataOutputStream(process.getOutputStream()); for (String command : commands) { if (command == null) { continue; } dos.write(command.getBytes()); dos.writeBytes(COMMAND_LINE_END); dos.flush(); } dos.writeBytes(COMMAND_EXIT); dos.flush(); status = process.waitFor(); errorMsg = new StringBuilder(); successReader = new BufferedReader(new InputStreamReader( process.getInputStream())); errorReader = new BufferedReader(new InputStreamReader( process.getErrorStream())); String lineStr; while ((lineStr = successReader.readLine()) != null) { results.add(lineStr); debug(" command line item : " + lineStr); } while ((lineStr = errorReader.readLine()) != null) { errorMsg.append(lineStr); } } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (dos != null) { dos.close(); } if (successReader != null) { successReader.close(); } if (errorReader != null) { errorReader.close(); } } catch (IOException e) { e.printStackTrace(); } if (process != null) { process.destroy(); } } debug(String.format(Locale.CHINA, "execute command end,errorMsg:%s,and status %d: ", errorMsg, status)); return results; } /** * DEBUG LOG * * @param message */ private static void debug(String message) { if (ISDEBUG) { Log.d(TAG, message); } } }
相關推薦
Android通過Runtime.getRuntime().exec實現Ping和Traceroute命令時readLine阻塞問題解決
在PC上呼叫cmd,進行一些常用的命令操作,在Android上的是通過Runtime.getRuntime().exec來執行底層Linux下的程式或指令碼(bat)。 首先連線上真機,電腦開啟CMD,輸入adb-shell,確保你要進行的指令碼語言是可以執行的。(比如
Android: 通過Runtime.getRuntime().exec呼叫底層Linux下的程式或指令碼
Android Runtime使得直接呼叫底層Linux下的可執行程式或指令碼成為可能 比如Linux下寫個測試工具,直接編譯後apk中通過Runtime來呼叫 或者寫個指令碼,apk中直接呼叫,省去中間層或者JNI 這個至少效率應該比較高吧 程式碼:
java調Python指令碼(五):java通過 Runtime.getRuntime().exec()調Python指令碼一直沒有返回值,卡住了,資料太大
1、背景: 當我們呼叫系統外部的某個程式,此時就可以用Runtime.getRuntime().exec()來呼叫。這次java調Python演算法程式碼時,一直沒有返回值,卡住了,而用pycharm跑Python程式碼是正常的,說明是java這邊的問題。去看了後臺的java程序一直都在,掛
Runtime.getRuntime().exec()實現Java呼叫python程式
使用Runtime.getRuntime().exec()來實現Java呼叫python,呼叫程式碼如下所示: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;
Runtime.getRuntime().exec(cmd,envp,dir)執行命令cmd中目錄含連續空格執行出錯
.get 導致 strong 問題 多少 cmd 缺失 就會 成了 場景:因cmd中含有jre路徑,而jre路徑因測試創建的目錄中含(haha)- -(haha) ,其中含有兩個空格,導致後續底層在截取,重組命令後缺失了一個空格,目錄中(haha)- -(haha)變成
Android Runtime.getRuntime().exec
exe runt amr stringbu clas ring tdi -s put try { // Executes the command. Process process = Runtime.getRunt
android Runtime.getRuntime().exec使用
1.read value: public String readRegister(String path){ try { Process process = Runtime.getRuntime().exec("/system/bin/cat
Android Runtime.getRuntime().exec() 使用方法
Android 可以通過Runtime.getRuntime().exec()方法來執行命令或者建立程序。 1. Runtime.getRuntime().exec共有六個過載方法: public Process exec(String command) 在單獨的程序
android 通過原生api(不需要opencv和第三方sdk)實現Camera人臉檢測
浪費了“黃金五年”的Java程式設計師,還有救嗎? >>>
Runtime.getRuntime().exec(cmd)執行adb shell腳本可能出現的問題
執行 eve (()) 十六進制 解決辦法 /dev/ dev exec 進制 例如:adb shell sendevent /dev/input/event3 1 $((0xca)) 1上面語句中含有$((0xca)) ,執行Runtime.getRuntime().ex
android 通過監聽edittext實現button的點擊事件
監聽 edittext 如果你沒有接第三方的輸入設備,那麽點擊按鈕只需找到你的button然後:button.performClick();就可以了那麽如果你用到第三方輸入法,有些時候監聽就沒有這麽好使了:以下場景為:外接輸入服務,直接給我丟一串字符,我拿到字符後執行按鈕事件代碼如下: editTe
Runtime.getRuntime().exec()需要註意的地方
window dsta 進程 明顯 trac get win 方法 mes 文章出處http://www.cnblogs.com/fclbky/p/6112180.html 有時候我們可能需要調用系統外部的某個程序,此時就可以用Runtime.getRuntime().e
在solaris上慎用Runtime.getRuntime().exec()
Java程序執行在Solaris上,如果程式碼中用了Runtime.getRuntime().exec(),啟動一個子程序執行一些命令,可能出現子程序掛住,導致父程序退出時,父程序所佔用的資源仍然沒有釋放,如埠等資訊,用ps -ef仍然可以看到父程序的資訊。用pstack可以看到fork資訊,在Ru
Android用SharedPreferences儲存資料實現註冊和登入功能(首次安裝預設開啟註冊,記住密碼)
註冊介面xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
Android listView item側滑實現刪除和置頂功能
第一次寫部落格,先說下大概思路吧~ 要顯示item側滑顯示刪除,置頂。首先要隱藏一部分item的佈局(自定義隱藏佈局寬度,在adapter裡設定LayoutParams)。然後重寫listview的onInterceptTouchEvent()和onTouchEvent(
Java執行Windows Dos bat指令碼:Runtime.getRuntime().exec
用Java編寫應用時,有時需要在程式中呼叫另一個現成的可執行程式或系統命令,這時可以通過組合使用Java提供的Runtime類和Process類的方法實現。下面是一種比較典型的程式模式: ... Process process = Runtime.
【區塊鏈】Android通過Geth RPC介面實現接入以太坊私有鏈
Android通過Geth RPC介面實現接入以太坊私有鏈 環境:mac os & android studio 一、啟動私有鏈 搭建方法見 here 啟動並設定RPC埠: geth --identity "linoy" --rpc -
Runtime.getRuntime().exec() 輸出流阻塞的解決方法
Java中用Runtime.getRuntime().exec() 呼叫外部程式, 獲取"標準輸出流", 老是阻塞. 在網上找了找, 覺得應該是"錯誤輸出流"的問題. 果然, 為"錯誤輸出流"單開一個執行緒讀取之, "標準輸出流"就不再阻塞了. 原始碼如下: /**
java Runtime.getRuntime().exec 呼叫系統指令碼/命令注意事項
錯誤的方法: //CPUID private static final String cpuid="dmidecode -t processor | grep 'ID' | head -1"; Process p = Runtime.getRuntime().exec
Runtime.getRuntime().exec執行阻塞問題解決
有時候我們可能需要呼叫系統外部的某個程式,此時就可以用Runtime.getRuntime().exec()來呼叫,他會生成一個新的程序去執行呼叫的程式。 此方法返回一個java.lang.Process物件,該物件可以得到之前開啟的程序的執行結果,還可以操作程序的輸入