Recently in the Android project, the need to execute command-line commands, previously found on the Internet not only messy and many mistakes, so I wrote a copy.
Words don't say much, directly on the code
ImportAndroid.util.Log;ImportJava.io.BufferedReader;ImportJava.io.DataOutputStream;ImportJava.io.InputStreamReader;ImportJava.util.concurrent.locks.Lock;ImportJava.util.concurrent.locks.ReadWriteLock;ImportJava.util.concurrent.locks.ReentrantReadWriteLock;Import StaticJava.lang.Runtime.getRuntime;/*** Class of execution command * Created by Kappa*/ Public classExecommand {//Shell Process Privateprocess process; //3 streams corresponding to a process PrivateBufferedReader Successresult; PrivateBufferedReader Errorresult; PrivateDataOutputStream os; //is synchronized, the True:run is blocked until it is complete or timed out. False:run will return immediately . Private Booleanbsynchronous; //indicates whether the shell process is still running Private BooleanBrunning =false; //Sync LockReadwritelock lock =NewReentrantreadwritelock (); //Save Execution Results PrivateStringBuffer result =NewStringBuffer (); /*** Constructor Function * *@paramSynchronous true: synchronous, false: Asynchronous*/ PublicExecommand (Booleansynchronous) {bsynchronous=synchronous; } /*** Default constructor, default is synchronous execution*/ PublicExecommand () {bsynchronous=true; } /*** has not started execution, and has been executed to complete both cases return false * *@returnWhether you are executing*/ Public Booleanisrunning () {returnbrunning; } /** * @returnreturn to execution results*/ PublicString GetResult () {Lock Readlock=Lock.readlock (); Readlock.lock (); Try { return NewString (Result); } finally{readlock.unlock (); } } /*** Execute Command * *@paramCommand Eg:cat/sdcard/test.txt *@parammaxtime Maximum wait time (MS) *@return This*/ PublicExecommand Run (String command,Final intmaxtime) {LOG.I ("Auto", "Run Command:" + Command + ", MaxTime:" +maxtime); if(Command = =NULL|| Command.length () = = 0) { return This; } Try{Process= GetRuntime (). EXEC ("sh"); } Catch(Exception e) {return This; } brunning=true; Successresult=NewBufferedReader (NewInputStreamReader (Process.getinputstream ())); Errorresult=NewBufferedReader (NewInputStreamReader (Process.geterrorstream ())); OS=NewDataOutputStream (Process.getoutputstream ()); Try { //write to SH to execute the commandOs.write (Command.getbytes ()); Os.writebytes ("\ n"); Os.flush (); Os.writebytes ("Exit\n"); Os.flush (); Os.close (); //If the wait time is set to non-positive, the timeout shutdown feature is not turned on if(MaxTime > 0) { //close process when timed out NewThread (NewRunnable () {@Override Public voidrun () {Try{thread.sleep (maxtime); } Catch(Exception e) {}Try { intRET =Process.exitvalue (); } Catch(illegalthreadstateexception e) {log.i ("Auto", "take maxtime,forced to destroy process"); Process.destroy (); }}). Start (); } //open a thread to process the input stream FinalThread T1 =NewThread (NewRunnable () {@Override Public voidrun () {String line; Lock Writelock=Lock.writelock (); Try { while(line = Successresult.readline ())! =NULL) { line+ = "\ n"; Writelock.lock (); Result.append (line); Writelock.unlock (); } } Catch(Exception e) {log.i ("Auto", "read InputStream exception:" +e.tostring ()); } finally { Try{successresult.close (); } Catch(Exception e) {log.i ("Auto", "Close InputStream exception:" +e.tostring ()); } } } }); T1.start (); //open a thread to handle the error stream FinalThread t2 =NewThread (NewRunnable () {@Override Public voidrun () {String line; Lock Writelock=Lock.writelock (); Try { while(line = Errorresult.readline ())! =NULL) { line+ = "\ n"; Writelock.lock (); Result.append (line); Writelock.unlock (); } } Catch(Exception e) {log.i ("Auto", "read Errorstream exception:" +e.tostring ()); } finally { Try{errorresult.close (); } Catch(Exception e) {log.i ("Auto", "read Errorstream exception:" +e.tostring ()); } } } }); T2.start (); Thread T3=NewThread (NewRunnable () {@Override Public voidrun () {Try { //wait for execution to completeT1.join (); T2.join (); Process.waitfor (); } Catch(Exception e) {}finally{brunning=false; LOG.I ("Auto", "Run Command process End"); } } }); T3.start (); if(bsynchronous) {t3.join (); } } Catch(Exception e) {log.i ("Auto", "Run Command Process exception:" +e.tostring ()); } return This; }}
To explain the key point, the first is to start a sh process, of course, if you use the root device, you can use SU.
This process contains input, output, error three streams, these three streams to be handled well, otherwise it may not be able to end the process normally,
There is also the execution of the command has ended, but still have input flow situation, also need to deal with.
Please refer to the code for other
There are 2 ways to use it. The first is the blocking mode, which is blocked until the command execution is complete, returning the command line output
String str = new Execommand (). Run (cmd, 10000). GetResult ();
There is also an asynchronous way, this call will be returned directly, then you can use GetResult () to obtain the results, using isrunning () to determine whether to complete, such as
New Execommand (false). Run ("Your cmd", 60000); while (Cmd.isrunning ()) { try { sleep (); Catch (Exception e) { } = cmd.getresult (); // Do something }
Android Command line execution Tool class