public static class Shell.Interactive
extends java.lang.Object
An interactive shell - initially created with Shell.Builder -
that executes blocks of commands you supply in the background, optionally
calling callbacks as each block completes.
STDERR output can be supplied as well, but due to compatibility with older Android versions, wantSTDERR is not implemented using redirectErrorStream, but rather appended to the output. STDOUT and STDERR are thus not guaranteed to be in the correct order in the output.
Note as well that the close() and waitForIdle() methods will intentionally crash when run in debug mode from the main thread of the application. Any blocking call should be run from a background thread.
When in debug mode, the code will also excessively log the commands passed to and the output returned from the shell.
Though this function uses background threads to gobble STDOUT and STDERR
so a deadlock does not occur if the shell produces massive output, the
output is still stored in a List<String>, and as such doing
something like 'ls -lR /' will probably have you run out of
memory when using a Shell.OnCommandResultListener. A work-around
is to not supply this callback, but using (only)
Shell.Builder#setOnSTDOUTLineListener(OnLineListener). This way,
an internal buffer will not be created and wasting your memory.
On which thread the callbacks execute is dependent on your
initialization. You can supply a custom Handler using
Shell.Builder.setHandler(Handler) if needed. If you do not supply
a custom Handler - unless you set
Shell.Builder.setAutoHandler(boolean) to false - a Handler will
be auto-created if the thread used for instantiation of the object has a
Looper.
If no Handler was supplied and it was also not auto-created, all callbacks will be called from either the STDOUT or STDERR gobbler threads. These are important threads that should be blocked as little as possible, as blocking them may in rare cases pause the native process or even create a deadlock.
The main thread must certainly have a Looper, thus if you call
Shell.Builder.open() from the main thread, a handler will (by
default) be auto-created, and all the callbacks will be called on the
main thread. While this is often convenient and easy to code with, you
should be aware that if your callbacks are 'expensive' to execute, this
may negatively impact UI performance.
Background threads usually do not have a Looper, so calling
Shell.Builder.open() from such a background thread will (by
default) result in all the callbacks being executed in one of the gobbler
threads. You will have to make sure the code you execute in these
callbacks is thread-safe.
| Modifier and Type | Method and Description |
|---|---|
void |
addCommand(java.util.List<java.lang.String> commands)
Add commands to execute
|
void |
addCommand(java.util.List<java.lang.String> commands,
int code,
Shell.OnCommandLineListener onCommandLineListener)
Add commands to execute, with a callback.
|
void |
addCommand(java.util.List<java.lang.String> commands,
int code,
Shell.OnCommandResultListener onCommandResultListener)
Add commands to execute, with a callback to be called on completion
(of all commands)
|
void |
addCommand(java.lang.String command)
Add a command to execute
|
void |
addCommand(java.lang.String[] commands)
Add commands to execute
|
void |
addCommand(java.lang.String[] commands,
int code,
Shell.OnCommandLineListener onCommandLineListener)
Add commands to execute, with a callback.
|
void |
addCommand(java.lang.String[] commands,
int code,
Shell.OnCommandResultListener onCommandResultListener)
Add commands to execute, with a callback to be called on completion
(of all commands)
|
void |
addCommand(java.lang.String command,
int code,
Shell.OnCommandLineListener onCommandLineListener)
Add a command to execute, with a callback.
|
void |
addCommand(java.lang.String command,
int code,
Shell.OnCommandResultListener onCommandResultListener)
Add a command to execute, with a callback to be called on completion
|
void |
close()
Close shell and clean up all resources.
|
protected void |
finalize() |
boolean |
hasHandler()
Are we using a Handler to post callbacks ?
|
boolean |
isIdle()
Have all commands completed executing ?
|
boolean |
isRunning()
Is our shell still running ?
|
void |
kill()
Try to clean up as much as possible from a shell that's gotten itself
wedged.
|
boolean |
waitForIdle()
Wait for idle state.
|
protected void finalize()
throws java.lang.Throwable
finalize in class java.lang.Objectjava.lang.Throwablepublic void addCommand(java.lang.String command)
command - Command to executepublic void addCommand(java.lang.String command,
int code,
Shell.OnCommandResultListener onCommandResultListener)
Add a command to execute, with a callback to be called on completion
The thread on which the callback executes is dependent on various
factors, see Shell.Interactive for further details
command - Command to executecode - User-defined value passed back to the callbackonCommandResultListener - Callback to be called on completionpublic void addCommand(java.lang.String command,
int code,
Shell.OnCommandLineListener onCommandLineListener)
Add a command to execute, with a callback. This callback gobbles the output line by line without buffering it and also returns the result code on completion.
The thread on which the callback executes is dependent on various
factors, see Shell.Interactive for further details
command - Command to executecode - User-defined value passed back to the callbackonCommandLineListener - Callbackpublic void addCommand(java.util.List<java.lang.String> commands)
commands - Commands to executepublic void addCommand(java.util.List<java.lang.String> commands,
int code,
Shell.OnCommandResultListener onCommandResultListener)
Add commands to execute, with a callback to be called on completion (of all commands)
The thread on which the callback executes is dependent on various
factors, see Shell.Interactive for further details
commands - Commands to executecode - User-defined value passed back to the callbackonCommandResultListener - Callback to be called on completion
(of all commands)public void addCommand(java.util.List<java.lang.String> commands,
int code,
Shell.OnCommandLineListener onCommandLineListener)
Add commands to execute, with a callback. This callback gobbles the output line by line without buffering it and also returns the result code on completion.
The thread on which the callback executes is dependent on various
factors, see Shell.Interactive for further details
commands - Commands to executecode - User-defined value passed back to the callbackonCommandLineListener - Callbackpublic void addCommand(java.lang.String[] commands)
commands - Commands to executepublic void addCommand(java.lang.String[] commands,
int code,
Shell.OnCommandResultListener onCommandResultListener)
Add commands to execute, with a callback to be called on completion (of all commands)
The thread on which the callback executes is dependent on various
factors, see Shell.Interactive for further details
commands - Commands to executecode - User-defined value passed back to the callbackonCommandResultListener - Callback to be called on completion
(of all commands)public void addCommand(java.lang.String[] commands,
int code,
Shell.OnCommandLineListener onCommandLineListener)
Add commands to execute, with a callback. This callback gobbles the output line by line without buffering it and also returns the result code on completion.
The thread on which the callback executes is dependent on various
factors, see Shell.Interactive for further details
commands - Commands to executecode - User-defined value passed back to the callbackonCommandLineListener - Callbackpublic void close()
public void kill()
public boolean isRunning()
public boolean isIdle()
public boolean waitForIdle()
Wait for idle state. As this is a blocking call, you should not call it from the main UI thread. If you do so and debug mode is enabled, this method will intentionally crash your app.
If not interrupted, this method will not return until all commands have finished executing. Note that this does not necessarily mean that all the callbacks have fired yet.
If no Handler is used, all callbacks will have been executed when this method returns. If a Handler is used, and this method is called from a different thread than associated with the Handler's Looper, all callbacks will have been executed when this method returns as well. If however a Handler is used but this method is called from the same thread as associated with the Handler's Looper, there is no way to know.
In practice this means that in most simple cases all callbacks will have completed when this method returns, but if you actually depend on this behavior, you should make certain this is indeed the case.
See Shell.Interactive for further details on threading and
handlers
public boolean hasHandler()