From 91365c6ae28a2a35557b13921d19533e68bbcfbb Mon Sep 17 00:00:00 2001 From: hyb1996 <946994919@qq.com> Date: Mon, 21 Jan 2019 14:09:59 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20Shell=E7=9A=84=E5=86=85?= =?UTF-8?q?=E5=AD=98=E6=B3=84=E6=BC=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/stardust/autojs/core/util/Shell.java | 45 ++++++++++++------- .../io/ByteBufferBackedInputStream.kt | 30 +++++++++++++ .../io/ByteBufferBackedOutputStream.kt | 19 ++++++++ 3 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 common/src/main/java/com/stardust/io/ByteBufferBackedInputStream.kt create mode 100644 common/src/main/java/com/stardust/io/ByteBufferBackedOutputStream.kt diff --git a/autojs/src/main/java/com/stardust/autojs/core/util/Shell.java b/autojs/src/main/java/com/stardust/autojs/core/util/Shell.java index 8e49ec78..976975e5 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/util/Shell.java +++ b/autojs/src/main/java/com/stardust/autojs/core/util/Shell.java @@ -5,9 +5,11 @@ import android.os.Handler; import android.preference.PreferenceManager; import android.util.Log; +import com.stardust.autojs.runtime.ScriptRuntime; import com.stardust.autojs.runtime.api.AbstractShell; import com.stardust.autojs.runtime.exception.ScriptInterruptedException; -import com.stardust.autojs.runtime.ScriptRuntime; +import com.stardust.io.ByteBufferBackedInputStream; +import com.stardust.io.ByteBufferBackedOutputStream; import com.stardust.lang.ThreadCompat; import com.stardust.pio.UncheckedIOException; @@ -15,8 +17,7 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; +import java.nio.ByteBuffer; import jackpal.androidterm.ShellTermSession; import jackpal.androidterm.emulatorview.TermSession; @@ -131,13 +132,13 @@ public class Shell extends AbstractShell { checkInitException(); throw new IllegalStateException(); } - }else { + } else { logDebug("ensureInitialized: init"); } } - private void logDebug(String log){ - if(DEBUG){ + private void logDebug(String log) { + if (DEBUG) { Log.d(TAG, log); } } @@ -150,7 +151,7 @@ public class Shell extends AbstractShell { private void waitInitialization() { synchronized (mInitLock) { - if(mInitialized){ + if (mInitialized) { return; } logDebug("waitInitialization: enter"); @@ -204,15 +205,16 @@ public class Shell extends AbstractShell { private class MyShellTermSession extends ShellTermSession { + private final ByteBuffer mByteBuffer = ByteBuffer.allocate(8192); private BufferedReader mBufferedReader; private OutputStream mOutputStream; private Thread mReadingThread; + private volatile boolean mReading = false; public MyShellTermSession(TermSettings settings, String initialCommand) throws IOException { super(settings, initialCommand); - PipedInputStream pipedInputStream = new PipedInputStream(8192); - mBufferedReader = new BufferedReader(new InputStreamReader(pipedInputStream)); - mOutputStream = new PipedOutputStream(pipedInputStream); + mBufferedReader = new BufferedReader(new InputStreamReader(new ByteBufferBackedInputStream(mByteBuffer))); + mOutputStream = new ByteBufferBackedOutputStream(mByteBuffer); if (mShouldReadOutput) { startReadingThread(); } @@ -222,14 +224,23 @@ public class Shell extends AbstractShell { mReadingThread = new ThreadCompat(() -> { String line; try { - while (!Thread.currentThread().isInterrupted() - && (line = mBufferedReader.readLine()) != null) { + while (true) { + if (!mReading) { + break; + } + synchronized (mByteBuffer) { + line = mBufferedReader.readLine(); + } + if (line == null) { + break; + } onNewLine(line); } } catch (IOException e) { e.printStackTrace(); } }); + mReading = true; mReadingThread.start(); } @@ -248,7 +259,7 @@ public class Shell extends AbstractShell { } } - private void onOutput(String str){ + private void onOutput(String str) { logDebug("onOutput: " + str); if (!mInitialized) { if (isRoot() && str.endsWith(":/ # ")) { @@ -265,7 +276,9 @@ public class Shell extends AbstractShell { protected void processInput(byte[] data, int offset, int count) { try { onOutput(new String(data, offset, count)); - mOutputStream.write(data, offset, count); + synchronized (mByteBuffer) { + mOutputStream.write(data, offset, count); + } } catch (IOException e) { e.printStackTrace(); finish(); @@ -304,8 +317,10 @@ public class Shell extends AbstractShell { super.finish(); if (!mShouldReadOutput) return; - if(mReadingThread != null){ + mReading = false; + if (mReadingThread != null) { mReadingThread.interrupt(); + mReadingThread = null; } try { mBufferedReader.close(); diff --git a/common/src/main/java/com/stardust/io/ByteBufferBackedInputStream.kt b/common/src/main/java/com/stardust/io/ByteBufferBackedInputStream.kt new file mode 100644 index 00000000..34b5fb74 --- /dev/null +++ b/common/src/main/java/com/stardust/io/ByteBufferBackedInputStream.kt @@ -0,0 +1,30 @@ +package com.stardust.io + +import java.io.IOException +import java.io.InputStream +import java.nio.ByteBuffer + +class ByteBufferBackedInputStream(private var buf: ByteBuffer) : InputStream() { + + @Throws(IOException::class) + override fun read(): Int { + return if (!buf.hasRemaining()) { + -1 + } else buf.get().toInt() and 0xFF + } + + @Throws(IOException::class) + override fun read(bytes: ByteArray, off: Int, len: Int): Int { + if (!buf.hasRemaining()) { + return -1 + } + val read = Math.min(len, available()) + buf.get(bytes, off, read) + buf.position(buf.position() - read) + return read + } + + override fun available(): Int { + return buf.position() + } +} \ No newline at end of file diff --git a/common/src/main/java/com/stardust/io/ByteBufferBackedOutputStream.kt b/common/src/main/java/com/stardust/io/ByteBufferBackedOutputStream.kt new file mode 100644 index 00000000..7c3ee425 --- /dev/null +++ b/common/src/main/java/com/stardust/io/ByteBufferBackedOutputStream.kt @@ -0,0 +1,19 @@ +package com.stardust.io + +import java.io.IOException +import java.io.OutputStream +import java.nio.ByteBuffer + +class ByteBufferBackedOutputStream(private var buf: ByteBuffer) : OutputStream() { + + @Throws(IOException::class) + override fun write(b: Int) { + buf.put(b.toByte()) + } + + @Throws(IOException::class) + override fun write(bytes: ByteArray, off: Int, len: Int) { + buf.put(bytes, off, len) + } + +} \ No newline at end of file