mirror of
https://github.com/TonyJiangWJ/Auto.js.git
synced 2026-06-24 21:33:16 +08:00
修复部分内存泄露问题
This commit is contained in:
parent
965839875f
commit
f41cab18d4
@ -1,7 +1,10 @@
|
||||
package com.stardust.autojs.core.looper;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
|
||||
@ -173,6 +173,7 @@ public class Loopers implements MessageQueue.IdleHandler {
|
||||
public void recycle() {
|
||||
quitServantLooper();
|
||||
mMainMessageQueue.removeIdleHandler(this);
|
||||
removeThreadLocalValue();
|
||||
}
|
||||
|
||||
public void setMainLooperQuitHandler(LooperQuitHandler mainLooperQuitHandler) {
|
||||
@ -195,11 +196,19 @@ public class Loopers implements MessageQueue.IdleHandler {
|
||||
Log.d(LOG_TAG, "looper queueIdle: " + l);
|
||||
if (shouldQuitLooper()) {
|
||||
l.quit();
|
||||
removeThreadLocalValue();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void removeThreadLocalValue() {
|
||||
maxWaitId.remove();
|
||||
waitIds.remove();
|
||||
looperQuitHandlers.remove();
|
||||
maxWaitId.remove();
|
||||
}
|
||||
|
||||
public void prepare() {
|
||||
if (Looper.myLooper() == null)
|
||||
LooperHelper.prepare();
|
||||
|
||||
@ -10,6 +10,8 @@ import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
|
||||
import com.stardust.concurrent.VolatileBox;
|
||||
import com.stardust.lang.ThreadCompat;
|
||||
|
||||
import org.mozilla.javascript.Context;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
@ -37,12 +39,12 @@ public class TimerThread extends ThreadCompat {
|
||||
@Override
|
||||
public void run() {
|
||||
mRuntime.loopers.prepare();
|
||||
mTimer = new Timer(mRuntime, mMaxCallbackUptimeMillisForAllThreads);
|
||||
sTimerMap.put(Thread.currentThread(), mTimer);
|
||||
((RhinoJavaScriptEngine) mRuntime.engines.myEngine()).enterContext();
|
||||
Context engineContext = ((RhinoJavaScriptEngine) mRuntime.engines.myEngine()).enterContext();
|
||||
notifyRunning();
|
||||
new Handler().post(mTarget);
|
||||
try {
|
||||
mTimer = new Timer(mRuntime, mMaxCallbackUptimeMillisForAllThreads);
|
||||
sTimerMap.put(Thread.currentThread(), mTimer);
|
||||
Looper.loop();
|
||||
} catch (Throwable e) {
|
||||
if (!ScriptInterruptedException.causedByInterrupted(e)) {
|
||||
@ -50,9 +52,9 @@ public class TimerThread extends ThreadCompat {
|
||||
}
|
||||
} finally {
|
||||
onExit();
|
||||
mTimer = null;
|
||||
org.mozilla.javascript.Context.exit();
|
||||
((RhinoJavaScriptEngine)mRuntime.engines.myEngine()).exitContext(engineContext);
|
||||
sTimerMap.remove(Thread.currentThread(), mTimer);
|
||||
mTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,6 +74,7 @@ public class TimerThread extends ThreadCompat {
|
||||
@CallSuper
|
||||
protected void onExit() {
|
||||
mRuntime.loopers.notifyThreadExit(this);
|
||||
LooperHelper.quitForThread(this);
|
||||
}
|
||||
|
||||
public static Timer getTimerForThread(Thread thread) {
|
||||
|
||||
@ -12,7 +12,10 @@ import com.stardust.autojs.runtime.ScriptRuntime
|
||||
import com.stardust.autojs.script.JavaScriptSource
|
||||
import com.stardust.automator.UiObjectCollection
|
||||
import com.stardust.pio.UncheckedIOException
|
||||
import org.mozilla.javascript.*
|
||||
import org.mozilla.javascript.Context
|
||||
import org.mozilla.javascript.Script
|
||||
import org.mozilla.javascript.Scriptable
|
||||
import org.mozilla.javascript.ScriptableObject
|
||||
import org.mozilla.javascript.commonjs.module.RequireBuilder
|
||||
import org.mozilla.javascript.commonjs.module.provider.SoftCachingModuleScriptProvider
|
||||
import java.io.File
|
||||
@ -153,6 +156,15 @@ open class RhinoJavaScriptEngine(private val mAndroidContext: android.content.Co
|
||||
return context
|
||||
}
|
||||
|
||||
fun exitContext(context: Context) {
|
||||
sContextEngineMap.remove(context)
|
||||
try {
|
||||
Context.exit()
|
||||
} catch (e: Exception) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
protected fun setupContext(context: Context) {
|
||||
context.optimizationLevel = -1
|
||||
context.languageVersion = Context.VERSION_ES6
|
||||
|
||||
@ -53,7 +53,9 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
mCacheDir = dir;
|
||||
mLibsDir = new File(dir, "libs");
|
||||
if (dir.exists()) {
|
||||
PFiles.deleteFilesOfDir(dir);
|
||||
if (!(parent instanceof AndroidClassLoader)) {
|
||||
PFiles.deleteFilesOfDir(dir);
|
||||
}
|
||||
} else {
|
||||
dir.mkdirs();
|
||||
}
|
||||
@ -136,6 +138,7 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
if (!file.exists()) {
|
||||
throw new FileNotFoundException(file.getPath());
|
||||
}
|
||||
Log.d(LOG_TAG, "dex file size: " + file.length());
|
||||
DexClassLoader loader = new DexClassLoader(file.getPath(), mCacheDir.getPath(), mLibsDir.getPath(), parent);
|
||||
// 根据dex文件名 移除已有的,使得最新载入的在LinkedHashMap末尾
|
||||
mDexClassLoaders.remove(file.getName());
|
||||
@ -167,6 +170,7 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
arguments.outName = dexFile.getPath();
|
||||
arguments.jarOutput = true;
|
||||
Main.run(arguments);
|
||||
Log.d(LOG_TAG, "dex file size: " + dexFile.length());
|
||||
DexClassLoader loader = loadDex(dexFile);
|
||||
if (isTmpDex) {
|
||||
Log.d(LOG_TAG, "delete tmpFile on finalize:" + dexFile.getName());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user