修复 Shell的内存泄漏问题

This commit is contained in:
hyb1996
2019-01-21 14:09:59 +08:00
parent 5cf08a92bf
commit 91365c6ae2
3 changed files with 79 additions and 15 deletions

View File

@@ -5,9 +5,11 @@ import android.os.Handler;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.api.AbstractShell; import com.stardust.autojs.runtime.api.AbstractShell;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException; 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.lang.ThreadCompat;
import com.stardust.pio.UncheckedIOException; import com.stardust.pio.UncheckedIOException;
@@ -15,8 +17,7 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PipedInputStream; import java.nio.ByteBuffer;
import java.io.PipedOutputStream;
import jackpal.androidterm.ShellTermSession; import jackpal.androidterm.ShellTermSession;
import jackpal.androidterm.emulatorview.TermSession; import jackpal.androidterm.emulatorview.TermSession;
@@ -131,13 +132,13 @@ public class Shell extends AbstractShell {
checkInitException(); checkInitException();
throw new IllegalStateException(); throw new IllegalStateException();
} }
}else { } else {
logDebug("ensureInitialized: init"); logDebug("ensureInitialized: init");
} }
} }
private void logDebug(String log){ private void logDebug(String log) {
if(DEBUG){ if (DEBUG) {
Log.d(TAG, log); Log.d(TAG, log);
} }
} }
@@ -150,7 +151,7 @@ public class Shell extends AbstractShell {
private void waitInitialization() { private void waitInitialization() {
synchronized (mInitLock) { synchronized (mInitLock) {
if(mInitialized){ if (mInitialized) {
return; return;
} }
logDebug("waitInitialization: enter"); logDebug("waitInitialization: enter");
@@ -204,15 +205,16 @@ public class Shell extends AbstractShell {
private class MyShellTermSession extends ShellTermSession { private class MyShellTermSession extends ShellTermSession {
private final ByteBuffer mByteBuffer = ByteBuffer.allocate(8192);
private BufferedReader mBufferedReader; private BufferedReader mBufferedReader;
private OutputStream mOutputStream; private OutputStream mOutputStream;
private Thread mReadingThread; private Thread mReadingThread;
private volatile boolean mReading = false;
public MyShellTermSession(TermSettings settings, String initialCommand) throws IOException { public MyShellTermSession(TermSettings settings, String initialCommand) throws IOException {
super(settings, initialCommand); super(settings, initialCommand);
PipedInputStream pipedInputStream = new PipedInputStream(8192); mBufferedReader = new BufferedReader(new InputStreamReader(new ByteBufferBackedInputStream(mByteBuffer)));
mBufferedReader = new BufferedReader(new InputStreamReader(pipedInputStream)); mOutputStream = new ByteBufferBackedOutputStream(mByteBuffer);
mOutputStream = new PipedOutputStream(pipedInputStream);
if (mShouldReadOutput) { if (mShouldReadOutput) {
startReadingThread(); startReadingThread();
} }
@@ -222,14 +224,23 @@ public class Shell extends AbstractShell {
mReadingThread = new ThreadCompat(() -> { mReadingThread = new ThreadCompat(() -> {
String line; String line;
try { try {
while (!Thread.currentThread().isInterrupted() while (true) {
&& (line = mBufferedReader.readLine()) != null) { if (!mReading) {
break;
}
synchronized (mByteBuffer) {
line = mBufferedReader.readLine();
}
if (line == null) {
break;
}
onNewLine(line); onNewLine(line);
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
}); });
mReading = true;
mReadingThread.start(); mReadingThread.start();
} }
@@ -248,7 +259,7 @@ public class Shell extends AbstractShell {
} }
} }
private void onOutput(String str){ private void onOutput(String str) {
logDebug("onOutput: " + str); logDebug("onOutput: " + str);
if (!mInitialized) { if (!mInitialized) {
if (isRoot() && str.endsWith(":/ # ")) { if (isRoot() && str.endsWith(":/ # ")) {
@@ -265,7 +276,9 @@ public class Shell extends AbstractShell {
protected void processInput(byte[] data, int offset, int count) { protected void processInput(byte[] data, int offset, int count) {
try { try {
onOutput(new String(data, offset, count)); onOutput(new String(data, offset, count));
mOutputStream.write(data, offset, count); synchronized (mByteBuffer) {
mOutputStream.write(data, offset, count);
}
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
finish(); finish();
@@ -304,8 +317,10 @@ public class Shell extends AbstractShell {
super.finish(); super.finish();
if (!mShouldReadOutput) if (!mShouldReadOutput)
return; return;
if(mReadingThread != null){ mReading = false;
if (mReadingThread != null) {
mReadingThread.interrupt(); mReadingThread.interrupt();
mReadingThread = null;
} }
try { try {
mBufferedReader.close(); mBufferedReader.close();

View File

@@ -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()
}
}

View File

@@ -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)
}
}