Optimize to reduce memory consumption

This commit is contained in:
ZaneYork 2021-01-29 09:51:01 +08:00
parent 3033a1b476
commit a4d6343935
3 changed files with 56 additions and 28 deletions

View File

@ -12,8 +12,8 @@ android {
applicationId "com.zane.smapiinstaller" applicationId "com.zane.smapiinstaller"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 30 targetSdkVersion 30
versionCode 65 versionCode 66
versionName "3.7.6.3" versionName "3.7.6.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true

View File

@ -110,8 +110,7 @@ public class ApkPatcher {
gamePackageName.set(packageName); gamePackageName.set(packageName);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
gameVersionCode.set(packageInfo.getLongVersionCode()); gameVersionCode.set(packageInfo.getLongVersionCode());
} } else {
else {
gameVersionCode.set(packageInfo.versionCode); gameVersionCode.set(packageInfo.versionCode);
} }
File apkFile = new File(sourceDir); File apkFile = new File(sourceDir);
@ -203,9 +202,6 @@ public class ApkPatcher {
List<ZipUtils.ZipEntrySource> entries = manifestEntries.stream() List<ZipUtils.ZipEntrySource> entries = manifestEntries.stream()
.map(entry -> processFileEntry(file, apkFilesManifest, entry, isAdvanced)) .map(entry -> processFileEntry(file, apkFilesManifest, entry, isAdvanced))
.filter(Objects::nonNull).flatMap(Stream::of).distinct().collect(Collectors.toList()); .filter(Objects::nonNull).flatMap(Stream::of).distinct().collect(Collectors.toList());
if (errorMessage.get() != null) {
return false;
}
entries.add(new ZipUtils.ZipEntrySource("AndroidManifest.xml", modifiedManifest, Deflater.DEFLATED)); entries.add(new ZipUtils.ZipEntrySource("AndroidManifest.xml", modifiedManifest, Deflater.DEFLATED));
emitProgress(10); emitProgress(10);
String patchedFilename = apkPath + ".patched"; String patchedFilename = apkPath + ".patched";
@ -244,33 +240,37 @@ public class ApkPatcher {
String filename = StringUtils.substringAfterLast(zipEntry.getName(), "/"); String filename = StringUtils.substringAfterLast(zipEntry.getName(), "/");
if (entryPath.equals(path) && StringUtils.wildCardMatch(filename, pattern)) { if (entryPath.equals(path) && StringUtils.wildCardMatch(filename, pattern)) {
byte[] bytes = ByteStreams.toByteArray(in); byte[] bytes = ByteStreams.toByteArray(in);
ZipUtils.ZipEntrySource source;
if (entry.isXALZ()) { if (entry.isXALZ()) {
bytes = ZipUtils.decompressXALZ(bytes); source = new ZipUtils.ZipEntrySource(entry.getTargetPath() + filename, bytes, entry.getCompression());
} else {
source = new ZipUtils.ZipEntrySource(entry.getTargetPath() + filename, entry.getCompression(), () -> ZipUtils.decompressXALZ(bytes));
} }
list.add(new ZipUtils.ZipEntrySource(entry.getTargetPath() + filename, bytes, entry.getCompression())); list.add(source);
} }
}); });
return list.toArray(new ZipUtils.ZipEntrySource[0]); return list.toArray(new ZipUtils.ZipEntrySource[0]);
} else { } else {
return Stream.of(context.getAssets().list(path)) return Stream.of(context.getAssets().list(path))
.filter(filename -> StringUtils.wildCardMatch(filename, pattern)) .filter(filename -> StringUtils.wildCardMatch(filename, pattern))
.map(filename -> { .map(filename -> new ZipUtils.ZipEntrySource(entry.getTargetPath() + filename, entry.getCompression(), () -> FileUtils.getAssetBytes(context, path + "/" + filename)))
byte[] bytes = FileUtils.getAssetBytes(context, path + "/" + filename);
return new ZipUtils.ZipEntrySource(entry.getTargetPath() + filename, bytes, entry.getCompression());
})
.toArray(ZipUtils.ZipEntrySource[]::new); .toArray(ZipUtils.ZipEntrySource[]::new);
} }
} catch (IOException ignored) { } catch (IOException ignored) {
} }
return null; return null;
} }
byte[] bytes; ZipUtils.ZipEntrySource source;
if (entry.getOrigin() == 1) { if (entry.getOrigin() == 1) {
bytes = ZipUtil.unpackEntry(apkFile, entry.getAssetPath()); byte[] unpackEntryBytes = ZipUtil.unpackEntry(apkFile, entry.getAssetPath());
if (entry.isXALZ()) { if (entry.isXALZ()) {
bytes = ZipUtils.decompressXALZ(bytes); source = new ZipUtils.ZipEntrySource(entry.getTargetPath(), entry.getCompression(), () -> ZipUtils.decompressXALZ(unpackEntryBytes));
} else {
source = new ZipUtils.ZipEntrySource(entry.getTargetPath(), unpackEntryBytes, entry.getCompression());
} }
} else { } else {
source = new ZipUtils.ZipEntrySource(entry.getTargetPath(), entry.getCompression(), () -> {
byte[] bytes;
if (entry.isExternal()) { if (entry.isExternal()) {
bytes = FileUtils.getAssetBytes(context, apkFilesManifest.getBasePath() + entry.getAssetPath()); bytes = FileUtils.getAssetBytes(context, apkFilesManifest.getBasePath() + entry.getAssetPath());
} else { } else {
@ -279,8 +279,10 @@ public class ApkPatcher {
if (StringUtils.isNoneBlank(entry.getPatchCrc())) { if (StringUtils.isNoneBlank(entry.getPatchCrc())) {
throw new NotImplementedException("bs patch mode is not supported anymore."); throw new NotImplementedException("bs patch mode is not supported anymore.");
} }
return bytes;
});
} }
return new ZipUtils.ZipEntrySource[]{new ZipUtils.ZipEntrySource(entry.getTargetPath(), bytes, entry.getCompression())}; return new ZipUtils.ZipEntrySource[]{source};
} }
/** /**
@ -332,8 +334,7 @@ public class ApkPatcher {
if (strObj.contains(ManifestPatchConstants.PATTERN_MAIN_ACTIVITY)) { if (strObj.contains(ManifestPatchConstants.PATTERN_MAIN_ACTIVITY)) {
if (versionCode.get() > 147) { if (versionCode.get() > 147) {
attr.obj = strObj.replaceFirst("\\w+\\.MainActivity", "crc648e5438a58262f792.SMainActivity"); attr.obj = strObj.replaceFirst("\\w+\\.MainActivity", "crc648e5438a58262f792.SMainActivity");
} } else {
else {
attr.obj = strObj.replaceFirst("\\w+\\.MainActivity", "md5723872fa9a204f7f942686e9ed9d0b7d.SMainActivity"); attr.obj = strObj.replaceFirst("\\w+\\.MainActivity", "md5723872fa9a204f7f942686e9ed9d0b7d.SMainActivity");
} }
} }

View File

@ -19,10 +19,13 @@ import java.nio.charset.StandardCharsets;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
/** /**
* @author Zane * @author Zane
@ -110,11 +113,35 @@ public class ZipUtils {
} }
@Data @Data
@RequiredArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@EqualsAndHashCode(of = "path") @EqualsAndHashCode(of = "path")
public static class ZipEntrySource { public static class ZipEntrySource {
@NonNull
private String path; private String path;
@NonNull
private byte[] data; private byte[] data;
@NonNull
private int compressionMethod; private int compressionMethod;
private Supplier<byte[]> dataSupplier;
public ZipEntrySource(@NonNull String path, @NonNull int compressionMethod, Supplier<byte[]> dataSupplier) {
this.path = path;
this.compressionMethod = compressionMethod;
this.dataSupplier = dataSupplier;
}
private byte[] getData() {
if(data != null) {
return data;
}
// Optimize: read only once
if(dataSupplier != null) {
byte[] bytes = dataSupplier.get();
dataSupplier = null;
return bytes;
}
return null;
}
} }
} }