尝试修复JavaAdapter无法正常使用的问题

This commit is contained in:
TonyJiangWJ 2020-05-15 21:57:38 +08:00
parent c03a28d67d
commit e2899e65e4
6 changed files with 79 additions and 21 deletions

View File

@ -21,7 +21,7 @@ import com.stardust.autojs.core.util.Shell;
import com.stardust.autojs.engine.LoopBasedJavaScriptEngine;
import com.stardust.autojs.engine.RootAutomatorEngine;
import com.stardust.autojs.engine.ScriptEngineManager;
import com.stardust.autojs.rhino.InterruptibleAndroidContextFactory;
import com.stardust.autojs.rhino.InterruptableAndroidContextFactory;
import com.stardust.autojs.runtime.ScriptRuntime;
import com.stardust.autojs.runtime.accessibility.AccessibilityConfig;
import com.stardust.autojs.runtime.api.AppUtils;
@ -129,7 +129,7 @@ public abstract class AutoJs {
}
protected void initContextFactory() {
ContextFactory.initGlobal(new InterruptibleAndroidContextFactory(new File(mContext.getCacheDir(), "classes")));
ContextFactory.initGlobal(new InterruptableAndroidContextFactory(new File(mContext.getCacheDir(), "classes")));
}
protected ScriptRuntime createRuntime() {

View File

@ -87,7 +87,7 @@ public class ScriptEngineService {
};
private static ScriptEngineService sInstance;
private static volatile ScriptEngineService sInstance;
private final Context mContext;
private UiHandler mUiHandler;
private final Console mGlobalConsole;
@ -209,8 +209,12 @@ public class ScriptEngineService {
}
public static void setInstance(ScriptEngineService service) {
if (sInstance != null) {
throw new IllegalStateException();
if (sInstance == null) {
synchronized (ScriptEngineService.class) {
if (sInstance != null) {
throw new IllegalStateException();
}
}
}
sInstance = service;
}

View File

@ -99,10 +99,19 @@ open class RhinoJavaScriptEngine(private val mAndroidContext: android.content.Co
@Synchronized
override fun destroy() {
super.destroy()
Log.d(LOG_TAG, "on destroy")
sContextEngineMap.remove(context)
Context.exit()
var destroySuccess = false;
try {
super.destroy()
Log.d(LOG_TAG, "on destroy")
sContextEngineMap.remove(context)
destroySuccess = true;
} finally {
if (destroySuccess)
Log.d(LOG_TAG, "destroy execute success")
else
Log.d(LOG_TAG, "destroy execute failed")
Context.exit()
}
}
override fun init() {
@ -151,6 +160,10 @@ open class RhinoJavaScriptEngine(private val mAndroidContext: android.content.Co
context.wrapFactory = WrapFactory()
}
protected fun removeContext(context: Context) {
context.wrapFactory = null
}
private inner class WrapFactory : org.mozilla.javascript.WrapFactory() {
override fun wrap(cx: Context, scope: Scriptable, obj: Any?, staticType: Class<*>?): Any? {

View File

@ -1,5 +1,7 @@
package com.stardust.autojs.rhino;
import java.util.WeakHashMap;
import android.util.Log;
import com.android.dx.command.dexer.Main;
@ -17,14 +19,11 @@ import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.TreeMap;
import dalvik.system.DexClassLoader;
@ -41,6 +40,8 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
private final File mCacheDir;
private final File mLibsDir;
private final WeakHashMap<DeleteOnFinalizeFile, String> weakDexFileMap = new WeakHashMap<>();
/**
* Create a new instance with the given parent classloader and cache dierctory
*
@ -168,7 +169,10 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
Main.run(arguments);
DexClassLoader loader = loadDex(dexFile);
if (isTmpDex) {
dexFile.delete();
Log.d(LOG_TAG, "delete tmpFile on finalize:" + dexFile.getName());
// 当弱引用失去引用时 删除File对象
weakDexFileMap.put(new DeleteOnFinalizeFile(dexFile), dexFile.getName());
Log.d(LOG_TAG, "current weakMap size:" + weakDexFileMap.size());
}
return loader;
}
@ -196,15 +200,26 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
throws ClassNotFoundException {
Class<?> loadedClass = findLoadedClass(name);
if (loadedClass == null) {
ListIterator<DexClassLoader> reverseIterator = new ArrayList<>(mDexClassLoaders.values()).listIterator(mDexClassLoaders.size());
while (reverseIterator.hasPrevious()) {
loadedClass = reverseIterator.previous().loadClass(name);
if (loadedClass != null) {
break;
if (parent != null) {
try {
loadedClass = parent.loadClass(name);
} catch (Exception e) {
// do nothing
}
}
if (loadedClass == null) {
loadedClass = parent.loadClass(name);
ListIterator<DexClassLoader> reverseIterator = new ArrayList<>(mDexClassLoaders.values()).listIterator(mDexClassLoaders.size());
while (reverseIterator.hasPrevious()) {
DexClassLoader classLoader = reverseIterator.previous();
// Log.d(LOG_TAG, "try to load class: " + name + " class loader info: " + classLoader.toString());
loadedClass = classLoader.loadClass(name);
if (loadedClass != null) {
break;
}
}
}
if (loadedClass == null) {
loadedClass = findClass(name);
}
}
return loadedClass;

View File

@ -0,0 +1,26 @@
package com.stardust.autojs.rhino;
import android.util.Log;
import java.io.File;
public class DeleteOnFinalizeFile {
private File fileObject;
private String LOG_TAG = "DeleteOnFinalizeFile";
public DeleteOnFinalizeFile(File file) {
fileObject = file;
}
@Override
protected void finalize() throws Throwable {
if (fileObject != null) {
Log.d(LOG_TAG, "finalize delete file" + fileObject.getName());
if (fileObject.exists())
fileObject.delete();
}
super.finalize();
}
}

View File

@ -10,7 +10,7 @@ import org.mozilla.javascript.Context;
import java.io.File;
import java.util.concurrent.atomic.AtomicInteger;
public class InterruptibleAndroidContextFactory extends AndroidContextFactory {
public class InterruptableAndroidContextFactory extends AndroidContextFactory {
private AtomicInteger mContextCount = new AtomicInteger();
private static final String LOG_TAG = "ContextFactory";
@ -20,7 +20,7 @@ public class InterruptibleAndroidContextFactory extends AndroidContextFactory {
*
* @param cacheDirectory the cache directory
*/
public InterruptibleAndroidContextFactory(File cacheDirectory) {
public InterruptableAndroidContextFactory(File cacheDirectory) {
super(cacheDirectory);
}