[Java] [Android] [Process] a brute-force service can solve all problems, Execute Command Line statements in a brute-force manner, and androidprocess
Execute Command Line statements in Java or Android. Similarly, a sub-process is created to execute and call Executable File Execution commands, similar to CMD in Windows.
In this case, you can execute the following two methods: ProcessBuilder and Runtime. The two creation methods have their own merits. For the differences, see [Java] [Android] [Process] ProcessBuilder and Runtime.
When creating sub-processes in Android to execute commands, there are certain restrictions:
1. The JVM provides limited memory.
2. The buffer range of the underlying layer is limited.
3. High concurrency can easily cause blocking.
We have to be careful when executing the command based on the above points and cannot create them at will.
In the previous article, I mentioned: [Java] [Android] [Process] Process Creation + Control + analysis experience. Some of my management methods have analyzed implementation. The final analysis is: when a sub-process is created, a thread is created to read the output stream information and exit immediately after the result is returned:
The above control method can effectively solve the problem that the underlying ProcessManager thread is dead (waiting for the IO buffer). When the thread dies, the child process will also wait and never exit. In this case, tens of thousands of commands can be executed without any problems. However, after half a month's observation, I found that this is not the most stable method. When there are many other IO operations in the program (such as file read/write and network requests; I encountered the same problem after running nearly 20 thousand command lines.
After the query, we can see that although we have started the thread to read excess stream data, when there are many threads or many requests, the thread may not be able to start immediately, but the IO is full at this time, the thread will enter the IO critical section and wait, that is, the thread is not omnipotent. Fortunately, there is a mechanism in Android: service.
What is the Android service? I don't want to talk about Baidu!
Now let's talk about my new ideas:
First, create a service and set the service as an independent process: android: process = ". command. CommandService"
Then, place the implementation Part in the service we opened, and use a class to Control Service start and call the service for task. The task is to put the above part in the service to control the implementation,
Is there no difference? Otherwise, the difference has come. First, because it is a service of an independent process, there will be an independent JVM space. At the same time, the IO of the process is not the same as that of the main thread (logically ); therefore, operations on other streams in the master process do not affect the stream of the independent process.
In addition, there is a particularly important situation: when an independent service process encounters a dead (IO) Wait condition, the daemon process in the service will automatically kill itself, and then wait for the restart to continue executing the task.
Implementation Code:
Public CommandServiceImpl () {// thread initialization Thread = new thread (CommandServiceImpl. class. getName () {@ Override public void run () {while (thread = this &&! This. isInterrupted () {if (commandExecutors! = Null & commandExecutors. size ()> 0) {lock. lock (); LogUtil. I (TAG, "Executors Size:" + commandExecutors. size (); for (CommandExecutor executor: commandExecutors) {if (executor. isTimeOut () try {killSelf ();} catch (RemoteException e) {e. printStackTrace ();} if (thread! = This & this. isInterrupted () break;} lock. unlock ();} try {Thread. sleep (10000);} catch (InterruptedException e) {e. printStackTrace () ;}}}; thread. setDaemon (true); thread. start ();}
<Span style = "white-space: pre"> </span>/*** kill yourself ** @ throws RemoteException */@ Override public void killSelf () throws RemoteException {android. OS. process. killProcess (android. OS. process. myPid ());}
/*** Run the command ** @ param params command * @ return result * @ throws RemoteException */@ Override public String command (String params) throws RemoteException {CommandExecutor executor = CommandExecutor. create (params); lock. lock (); commandExecutors. add (executor); lock. unlock (); String result = executor. getResult (); lock. lock (); commandExecutors. remove (executor); lock. unlock (); return result ;}
At this time, because the service cannot save the current queue task in the memory because it kills itself, will the task be discarded? This is definitely not allowed. We cannot control the task in the service, but we can control the task:
The Code is as follows:
Package net. qiujuer. libraries. genius. command; import android. content. componentName; import android. content. context; import android. content. intent; import android. content. serviceConnection; import android. OS. IBinder; import net. qiujuer. libraries. genius. journal. logUtil; import net. qiujuer. libraries. genius. utils. globalValue; import java. util. concurrent. locks. condition; import java. util. concurrent. locks. lock; im Port java. util. concurrent. locks. reentrantLock;/*** Created by Genius on 2014/8/13. * run the Model */public class CommandModel {private static final String TAG = CommandModel. class. getName (); // call the service interface private static ICommandInterface iService = null; // service link class, used to instantiate the service interface private static ServiceConnection conn = new ServiceConnection () {@ Override public void onServiceConnected (ComponentName name, IBinde R service) {iLock. lock (); iService = ICommandInterface. Stub. asInterface (service); if (iService! = Null) {try {iCondition. signalAll ();} catch (Exception e) {e. printStackTrace () ;}} else bindService (); iLock. unlock (); LogUtil. I (TAG, "onServiceConnected") ;}@ Override public void onServiceDisconnected (ComponentName name) {iService = null; LogUtil. I (TAG, "onServiceDisconnected") ;}}; // Lock private static Lock iLock = new ReentrantLock (); // wait and wake up private static Condition iCondition = iLock. newCondition (); // run the private String parameter; // whether to cancel the test private boolean isCancel;/*** instantiate ** @ param params command parameter eg: "/system/bin/ping", "-c", "4", "-s", "100", "www.qiujuer.net" */public CommandModel (String... params) {// check params if (params = null) throw new NullPointerException (); // run StringBuilder sb = new StringBuilder (); for (String str: params) {sb. append (str); sb. append ("");} this. parameter = sb. toString ();}/*** run the test ** @ param model ProcessModel * @ return result */public static String command (CommandModel model) {// check whether the test if (model. isCancel) return null; // check Service if (iService = null) {iLock. lock (); try {iCondition. await ();} catch (InterruptedException e) {e. printStackTrace ();} iLock. unlock () ;}string result; try {result = iService. command (model. parameter);} catch (Exception e) {e. printStackTrace (); bindService (); result = command (model);} return result;}/*** start and bind Service */private static void bindService () {Context context = GlobalValue. getContext (); Intent intent = new Intent (context, CommandService. class); context. startService (intent); context. bindService (intent, conn, Context. BIND_AUTO_CREATE);}/*** cancel test */public void cancel () {isCancel = true;}/*** static initialization */static {bindService ();}}
Where:
Public static String command (CommandModel model) {// checks whether to cancel the test if (model. isCancel) return null; // check Service if (iService = null) {iLock. lock (); try {iCondition. await ();} catch (InterruptedException e) {e. printStackTrace ();} iLock. unlock () ;}string result; try {result = iService. command (model. parameter);} catch (Exception e) {e. printStackTrace (); bindService (); result = command (model);} return result ;}
Callback is used to complete the task execution!
Independent process service interface: ICommandInterface. aidl
interface ICommandInterface { void killSelf(); String command(String params);}
Command Executor (actual function implementation in the Service): CommandExecutor. java
Package net. qiujuer. libraries. genius. command; import net. qiujuer. libraries. genius. journal. logUtil; import net. qiujuer. libraries. genius. utils. toolUtil; import java. io. bufferedReader; import java. io. IOException; import java. io. inputStream; import java. io. inputStreamReader; import java. io. outputStream; import java. util. concurrent. locks. lock; import java. util. concurrent. locks. reentrantLock;/*** Created by Geni Us on 2014/8/13. * run the command line */class CommandExecutor {private static final String TAG = CommandExecutor. class. getName (); // linefeed private static final String BREAK_LINE; // Error BUFFER private static final byte [] BUFFER; // BUFFER size private static final int BUFFER_LENGTH; // private static final Lock = new ReentrantLock () must be mutually exclusive during process creation; // private static final long TIMEOUT = 60000 within 1 minute; // ProcessBuilder priva Te static ProcessBuilder PRC; final private Process process; final private InputStream in; final private InputStream err; final private OutputStream out; final private StringBuilder sbReader; private BufferedReader bInReader = null; private InputStreamReader isInReader = null; private boolean isDone; private long startTime;/*** static variable initialization */static {BREAK_LINE = "\ n"; BUFFER_LENGTH = 128; BUFFER = New byte [BUFFER_LENGTH]; LOCK. lock (); PRC = new ProcessBuilder (); LOCK. unlock ();}/*** instantiate a CommandExecutor ** @ param process Process */private CommandExecutor (Process process) {// init this. startTime = System. currentTimeMillis (); this. process = process; // get out = process. getOutputStream (); in = process. getInputStream (); err = process. getErrorStream (); // in if (in! = Null) {isInReader = new InputStreamReader (in); bInReader = new BufferedReader (isInReader, BUFFER_LENGTH);} sbReader = new StringBuilder (); // start read thread Thread processThread = new Thread (TAG) {@ Override public void run () {startRead () ;}}; processThread. setDaemon (true); processThread. start ();}/*** Run Command ** @ param command parameter eg: "/system/bin/ping-c 4-s 100 www.qiujuer.net" */protec Ted static CommandExecutor create (String param) {String [] params = param. split (""); CommandExecutor processModel = null; try {LOCK. lock (); Process process = PRC. command (params ). redirectErrorStream (true ). start (); processModel = new CommandExecutor (process);} catch (IOException e) {e. printStackTrace ();} finally {// sleep 100 ToolUtil. sleepIgnoreInterrupt (100); LOCK. unlock ();} return process Model;}/*** get whether time-out ** @ return whether time-out */protected boolean isTimeOut () {return (System. currentTimeMillis ()-startTime)> = TIMEOUT);} // read the private void read () {String str; // read In try {while (str = bInReader. readLine ())! = Null) {sbReader. append (str); sbReader. append (BREAK_LINE) ;}} catch (Exception e) {String err = e. getMessage (); if (err! = Null & err. length ()> 0) {LogUtil. e (TAG, "Read Exception:" + err) ;}}/*** start thread to asynchronously Read the result */private void startRead () {// while to end while (true) {try {process. exitValue (); // read last read (); break;} catch (IllegalThreadStateException e) {read () ;} ToolUtil. sleepIgnoreInterrupt (50);} // read end int len; if (in! = Null) {try {while (len = in. read (BUFFER)> 0) {LogUtil. d (TAG, "Read End:" + len) ;}} catch (IOException e) {String err = e. getMessage (); if (err! = Null & err. length ()> 0) LogUtil. e (TAG, "Read Thread IOException:" + err) ;}// close (); // destroy (); // done isDone = true ;} /*** get execution result ** @ return result */protected String getResult () {// until startRead en while (! IsDone) {ToolUtil. sleepIgnoreInterrupt (200);} // return if (sbReader. length () = 0) return null; else return sbReader. toString ();}/*** close all streams */private void close () {// close out if (out! = Null) {try {out. close () ;}catch (IOException e) {e. printStackTrace () ;}// err if (err! = Null) {try {err. close () ;}catch (IOException e) {e. printStackTrace () ;}// in if (in! = Null) {try {in. close () ;}catch (IOException e) {e. printStackTrace () ;}} if (isInReader! = Null) {try {isInReader. close () ;}catch (IOException e) {e. printStackTrace () ;}} if (bInReader! = Null) {try {bInReader. close ();} catch (IOException e) {e. printStackTrace () ;}}/ *** destroy */private void destroy () {String str = process. toString (); try {int I = str. indexOf ("=") + 1; int j = str. indexOf ("]"); str = str. substring (I, j); int pid = Integer. parseInt (str); try {android. OS. process. killProcess (pid);} catch (Exception e) {try {process. destroy ();} catch (Exception ex) {ex. printStackTrace () ;}} catch (Exception e) {e. printStackTrace ();}}}
Well, this brute force method is almost over. It can be said that the execution of command parameters is a perfect method. In this way, I run the Ping test for 0.1 million times, the number of concurrent tasks reaches 500 at the same time. The tested device is meizu M9.
This code has been packaged into my own class library and open-source to GitHub; Address: Genius-Android
I hope you will migrate more of my projects. This Class Library also contains a self-developed complete log system. Other things will be added in the future, such as processing slice (Fuzzy)
If you want to use java to call cmd, You can execute the statement directly called in cmd.
The command processor (cmd.exe) is explained as follows:
Process p = runtime.getruntime(cmd.exe c ("cmd/c dir c :\\");
The command processor does not need to be interpreted as follows:
Process p = runtime.getruntime(cmd.exe c ("\" 16-bit flash programm \ "I com3 1.hex ");
An error occurred while executing statements in JDBC in java
Con. prepareStatement ("source d: okercn. SQL ");
In prepareStatement, only SQL statements such as (select * from table) or delete from table can be executed. Instead of executing this command.
The command is executed through some methods in the system class. You can check the API. .