mirror of
https://github.com/TonyJiangWJ/Auto.js.git
synced 2026-06-21 21:01:43 +08:00
feat: runtime.loadJar() cache dex
This commit is contained in:
parent
94395544b7
commit
6cebca179c
Binary file not shown.
@ -16,8 +16,8 @@ android {
|
||||
applicationId "org.autojs.autojs"
|
||||
minSdkVersion versions.mini
|
||||
targetSdkVersion versions.target
|
||||
versionCode 423
|
||||
versionName "4.0.3 Alpha4"
|
||||
versionCode versions.appVersionCode
|
||||
versionName versions.appVersionName
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
multiDexEnabled true
|
||||
ndk {
|
||||
|
||||
@ -3,7 +3,8 @@ package com.stardust.autojs.rhino;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.dx.command.dexer.Main;
|
||||
import com.android.dx.dex.file.DexFile;
|
||||
import com.stardust.pio.PFiles;
|
||||
import com.stardust.util.MD5;
|
||||
|
||||
import net.lingala.zip4j.core.ZipFile;
|
||||
import net.lingala.zip4j.exception.ZipException;
|
||||
@ -16,6 +17,7 @@ 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.List;
|
||||
|
||||
@ -42,7 +44,11 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
public AndroidClassLoader(ClassLoader parent, File dir) {
|
||||
this.parent = parent;
|
||||
mCacheDir = dir;
|
||||
dir.mkdirs();
|
||||
if (dir.exists()) {
|
||||
PFiles.deleteFilesOfDir(dir);
|
||||
} else {
|
||||
dir.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,13 +59,13 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
Log.d(LOG_TAG, "defineClass: name = " + name + " data.length = " + data.length);
|
||||
File classFile = null;
|
||||
try {
|
||||
classFile = generateTempClassFile(name, false);
|
||||
classFile = generateTempFile(name, false);
|
||||
final ZipFile zipFile = new ZipFile(classFile);
|
||||
final ZipParameters parameters = new ZipParameters();
|
||||
parameters.setFileNameInZip(name.replace('.', '/') + ".class");
|
||||
parameters.setSourceExternalStream(true);
|
||||
zipFile.addStream(new ByteArrayInputStream(data), parameters);
|
||||
return dexJar(classFile).loadClass(name);
|
||||
return dexJar(classFile, null).loadClass(name);
|
||||
} catch (IOException | ZipException | ClassNotFoundException e) {
|
||||
throw new FatalLoadingException(e);
|
||||
} finally {
|
||||
@ -69,7 +75,7 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
}
|
||||
}
|
||||
|
||||
private File generateTempClassFile(String name, boolean create) throws IOException {
|
||||
private File generateTempFile(String name, boolean create) throws IOException {
|
||||
File file = new File(mCacheDir, name.hashCode() + System.currentTimeMillis() + ".jar");
|
||||
if (create) {
|
||||
if (!file.exists()) {
|
||||
@ -83,8 +89,16 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
|
||||
public void loadJar(File jar) throws IOException {
|
||||
Log.d(LOG_TAG, "loadJar: jar = " + jar);
|
||||
if (!jar.exists() || !jar.canRead()) {
|
||||
throw new FileNotFoundException("File does not exist or readable: " + jar.getPath());
|
||||
}
|
||||
File dexFile = new File(mCacheDir, generateDexFileName(jar));
|
||||
if (dexFile.exists()) {
|
||||
loadDex(dexFile);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final File classFile = generateTempClassFile(jar.getPath(), false);
|
||||
final File classFile = generateTempFile(jar.getPath(), false);
|
||||
final ZipFile zipFile = new ZipFile(classFile);
|
||||
final ZipFile jarFile = new ZipFile(jar);
|
||||
//noinspection unchecked
|
||||
@ -96,12 +110,22 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
zipFile.addStream(jarFile.getInputStream(header), parameters);
|
||||
}
|
||||
}
|
||||
dexJar(classFile);
|
||||
dexJar(classFile, dexFile);
|
||||
classFile.delete();
|
||||
} catch (ZipException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String generateDexFileName(File jar) {
|
||||
String message = jar.getPath() + "_" + jar.lastModified();
|
||||
try {
|
||||
return MD5.md5(message);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public DexClassLoader loadDex(File file) throws FileNotFoundException {
|
||||
Log.d(LOG_TAG, "loadDex: file = " + file);
|
||||
if (!file.exists()) {
|
||||
@ -112,15 +136,20 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
|
||||
return loader;
|
||||
}
|
||||
|
||||
private DexClassLoader dexJar(File classFile) throws IOException {
|
||||
private DexClassLoader dexJar(File classFile, File dexFile) throws IOException {
|
||||
final Main.Arguments arguments = new Main.Arguments();
|
||||
arguments.fileNames = new String[]{classFile.getPath()};
|
||||
File dexFile = generateTempClassFile("dex-" + classFile.getPath(), true);
|
||||
boolean isTmpDex = dexFile == null;
|
||||
if (isTmpDex) {
|
||||
dexFile = generateTempFile("dex-" + classFile.getPath(), true);
|
||||
}
|
||||
arguments.outName = dexFile.getPath();
|
||||
arguments.jarOutput = true;
|
||||
Main.run(arguments);
|
||||
DexClassLoader loader = loadDex(dexFile);
|
||||
dexFile.delete();
|
||||
if (isTmpDex) {
|
||||
dexFile.delete();
|
||||
}
|
||||
return loader;
|
||||
}
|
||||
|
||||
|
||||
10
build.gradle
10
build.gradle
@ -28,9 +28,11 @@ task clean(type: Delete) {
|
||||
|
||||
ext {
|
||||
versions = [
|
||||
target: 28,
|
||||
mini: 17,
|
||||
compile: 28,
|
||||
buildTool: '28.0.3'
|
||||
appVersionCode: 423,
|
||||
appVersionName: '4.0.3 Alpha4',
|
||||
target : 28,
|
||||
mini : 17,
|
||||
compile : 28,
|
||||
buildTool : '28.0.3'
|
||||
]
|
||||
}
|
||||
|
||||
@ -395,6 +395,19 @@ public class PFiles {
|
||||
return file.delete();
|
||||
}
|
||||
|
||||
public static boolean deleteFilesOfDir(File dir) {
|
||||
if (!dir.isDirectory())
|
||||
throw new IllegalArgumentException("not a directory: " + dir);
|
||||
File[] children = dir.listFiles();
|
||||
if (children != null) {
|
||||
for (File child : children) {
|
||||
if (!deleteRecursively(child))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean remove(String path) {
|
||||
return new File(path).delete();
|
||||
}
|
||||
|
||||
26
common/src/main/java/com/stardust/util/MD5.java
Normal file
26
common/src/main/java/com/stardust/util/MD5.java
Normal file
@ -0,0 +1,26 @@
|
||||
package com.stardust.util;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class MD5 {
|
||||
|
||||
public static byte[] md5Bytes(String message) throws NoSuchAlgorithmException {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.update(message.getBytes());
|
||||
return md5.digest();
|
||||
}
|
||||
|
||||
public static String md5(String message) throws NoSuchAlgorithmException {
|
||||
byte[] bytes = md5Bytes(message);
|
||||
StringBuilder hexString = new StringBuilder(32);
|
||||
for (byte b : bytes) {
|
||||
String hex = Integer.toHexString(0xFF & b);
|
||||
if (hex.length() == 1) {
|
||||
hexString.append('0');
|
||||
}
|
||||
hexString.append(hex);
|
||||
}
|
||||
return hexString.toString();
|
||||
}
|
||||
}
|
||||
@ -8,8 +8,8 @@ android {
|
||||
applicationId "com.stardust.auojs.inrt"
|
||||
minSdkVersion versions.mini
|
||||
targetSdkVersion versions.target
|
||||
versionCode 210
|
||||
versionName "4.0.2 Alpha5"
|
||||
versionCode versions.appVersionCode - 200
|
||||
versionName versions.appVersionName
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a'
|
||||
|
||||
@ -26,7 +26,8 @@
|
||||
android:label="inrt"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme"
|
||||
tools:replace="android:label, android:allowBackup">
|
||||
tools:replace="android:label, android:allowBackup"
|
||||
tools:ignore="GoogleAppIndexingWarning">
|
||||
<activity android:name=".LogActivity">
|
||||
|
||||
</activity>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user