Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
topjohnwu authored Feb 21, 2018
1 parent c64e86c commit 16bc300
Showing 1 changed file with 43 additions and 7 deletions.
50 changes: 43 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

An Android library that provides APIs to a Unix (root) shell.

Some poorly coded applications requests a new shell (call `su`, or worse `su -c <commands>`) for every single command, which is very inefficient. This library makes sharing a single, globally shared shell session in Android applications super easy: developers don't have to worry about concurrency issues, and it comes with a rich selection of both synchronous and asynchronous APIs to create a powerful root app.
Some poorly coded applications requests a new shell (call `su`, or worse `su -c <commands>`) for every single command, which is very inefficient. This library makes sharing a single, globally shared shell session in Android applications super easy: developers won't have to bother about concurrency issues, and with a rich selection of both synchronous and asynchronous APIs, it is much easier to create a powerful root app.

This library bundles with full featured `busybox` binaries. App developers can easily setup and create an internal `busybox` environment with the built-in helper method without relying on potentially flawed (or even no) external `busybox`. If you don't need the additional `busybox` binaries and willing to minimize APK size, [Proguard](https://developer.android.com/studio/build/shrink-code.html) is smart enough to remove the binaries for you.

`libsu` also comes with a whole suite of I/O classes, re-creating `java.io` classes but enhanced with root access. Without even thinking about command-lines, you can use `File`, `RandomAccessFile`, `FileInputStream`, and `FileOutputStream` equivalents on all files that are only accessible with root permissions. The I/O stream classes are carefully optimized and have very promising performance.

One complex Android application using `libsu` for all root related operations is [Magisk Manager](https://github.com/topjohnwu/MagiskManager).

Expand All @@ -14,21 +18,26 @@ repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation 'com.github.topjohnwu:libsu:1.0.1'
implementation 'com.github.topjohnwu:libsu:1.1.1'
}
```

## Simple Tutorial

### Setup
Subclass `Shell.ContainerApp` and use it as your `Application`:
Subclass `Shell.ContainerApp` and use it as your `Application`.
Set flags, initializers, or busybox as soon as possible:

```java
public class ExampleApp extends Shell.ContainerApp {
public ExampleApp() {
// Set some flags here if you need
@Override
public void onCreate() {
super.onCreate();
// Set flags
Shell.setFlags(Shell.FLAG_REDIRECT_STDERR);
Shell.verboseLogging(BuildConfig.DEBUG);
// Use internal busybox
BusyBox.setup(this);
}
}
```
Expand Down Expand Up @@ -90,14 +99,41 @@ List<String> callbackList = new CallbackList<String>() {
Shell.Async.su(callbackList, "for i in 1 2 3 4 5; do echo $i; sleep 1; done");
```

### I/O
`libsu` also comes with a rich suite of I/O classes for developers to access files using the shared root shell:

```java
/* Treat files that require root access just like ordinary files */
SuFile logs = new SuFile("/cache/magisk.log");
if (logs.exists()) {
try (InputStream in = new SuFileInputStream(logs);
OutputStream out = new SuFileOutputStream("/data/magisk.log.bak")) {
/* All file data can be accessed by Java Streams */

// For example, use a helper method to copy the logs
ShellUtils.pump(in, out);
} catch (IOException e) {
e.printStackTrace();
}
}
```

### Advanced
Initialize the shell with custom `Shell.Initializer`, similar to what `.bashrc` will do.

```java
Shell.setInitializer(new Shell.Initializer() {
@Override
public void onRootShellInit(@NonNull Shell shell) {
shell.run(null, null, "export PATH=" + BUSYBOX_PATH + ":$PATH");
/* Construct the initializer within Application if you need Context reference
* like the example below (getResources()). Application contexts won't leak memory, but
* Activities do! */
try (InputStream bashrc = getResources().openRawResource(R.raw.bashrc)) {
// Load a script from raw resources
shell.loadInputStream(null, null, bashrc);
} catch (IOException e) {
e.printStackTrace();
}
}
});
```
Expand All @@ -106,4 +142,4 @@ Shell.setInitializer(new Shell.Initializer() {

This repo also comes with an example app (`:example`), check the code and play/experiment with it.

More detailed full documentation is in the project's [JavaDoc Page](https://topjohnwu.github.io/libsu).
I strongly recommend all developers to check out the more detailed full documentation: [JavaDoc Page](https://topjohnwu.github.io/libsu).

0 comments on commit 16bc300

Please sign in to comment.