From 16bc30036f3c411bdf950ee6ebced29f011ff3fc Mon Sep 17 00:00:00 2001 From: John Wu Date: Thu, 22 Feb 2018 00:33:38 +0800 Subject: [PATCH] Update README.md --- README.md | 50 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index cc3ae2bd..e7b9902a 100644 --- a/README.md +++ b/README.md @@ -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 `) 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 `) 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). @@ -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); } } ``` @@ -90,6 +99,25 @@ List callbackList = new CallbackList() { 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. @@ -97,7 +125,15 @@ Initialize the shell with custom `Shell.Initializer`, similar to what `.bashrc` 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(); + } } }); ``` @@ -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).