修复 Shell的内存泄漏问题
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user