feat: Download JREs from github

This should help reduce apk size.
We still maintain Java 8 due to reasons.

All old legacy code for having internal runtimes were not removed
because we have no reason to.
This commit is contained in:
alexytomi
2026-04-03 01:44:42 +08:00
parent 32d987c1b0
commit afaa9bda94
4 changed files with 101 additions and 34 deletions

View File

@@ -38,35 +38,35 @@ jobs:
branch: buildjre8
name: jre8-pojav
- name: Get JRE17
uses: dawidd6/action-download-artifact@v9
with:
workflow: build.yml
path: app_pojavlauncher/src/main/assets/components/jre-new
workflow_conclusion: completed
repo: AngelAuraMC/angelauramc-openjdk-build
branch: buildjre17-21
name: jre17-pojav
- name: Get JRE21
uses: dawidd6/action-download-artifact@v9
with:
workflow: build.yml
path: app_pojavlauncher/src/main/assets/components/jre-21
workflow_conclusion: completed
repo: AngelAuraMC/angelauramc-openjdk-build
branch: buildjre17-21
name: jre21-pojav
- name: Get JRE25
uses: dawidd6/action-download-artifact@v9
with:
workflow: build.yml
path: app_pojavlauncher/src/main/assets/components/jre-25
workflow_conclusion: completed
repo: FCL-Team/Android-OpenJDK-Build
branch: Build_JRE_25
name: jre25-multiarch
# - name: Get JRE17
# uses: dawidd6/action-download-artifact@v9
# with:
# workflow: build.yml
# path: app_pojavlauncher/src/main/assets/components/jre-new
# workflow_conclusion: completed
# repo: AngelAuraMC/angelauramc-openjdk-build
# branch: buildjre17-21
# name: jre17-pojav
#
# - name: Get JRE21
# uses: dawidd6/action-download-artifact@v9
# with:
# workflow: build.yml
# path: app_pojavlauncher/src/main/assets/components/jre-21
# workflow_conclusion: completed
# repo: AngelAuraMC/angelauramc-openjdk-build
# branch: buildjre17-21
# name: jre21-pojav
#
# - name: Get JRE25
# uses: dawidd6/action-download-artifact@v9
# with:
# workflow: build.yml
# path: app_pojavlauncher/src/main/assets/components/jre-25
# workflow_conclusion: completed
# repo: FCL-Team/Android-OpenJDK-Build
# branch: Build_JRE_25
# name: jre25-multiarch
- uses: gradle/actions/setup-gradle@v4
with:

View File

@@ -1,18 +1,34 @@
package net.kdt.pojavlaunch;
import static net.kdt.pojavlaunch.Architecture.archAsString;
import static net.kdt.pojavlaunch.Architecture.getDeviceArchitecture;
import static net.kdt.pojavlaunch.Tools.NATIVE_LIB_DIR;
import static net.kdt.pojavlaunch.Tools.downloadFile;
import static net.kdt.pojavlaunch.Tools.isOnline;
import android.app.Activity;
import android.content.res.AssetManager;
import android.util.Log;
import androidx.appcompat.app.AlertDialog;
import com.kdt.mcgui.ProgressLayout;
import net.kdt.pojavlaunch.multirt.MultiRTUtils;
import net.kdt.pojavlaunch.multirt.Runtime;
import net.kdt.pojavlaunch.progresskeeper.DownloaderProgressWrapper;
import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper;
import net.kdt.pojavlaunch.utils.DownloadUtils;
import net.kdt.pojavlaunch.utils.JREUtils;
import net.kdt.pojavlaunch.utils.MathUtils;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
@@ -84,7 +100,7 @@ public class NewJREUtil {
// Check whether the selection is an internal runtime
InternalRuntime internalRuntime = getInternalRuntime(runtime);
// If it is, check if updates are available from the APK file
if(internalRuntime != null) {
if (internalRuntime != null) {
// Not calling showRuntimeFail on failure here because we did, technically, find the compatible runtime
return checkInternalRuntime(assetManager, internalRuntime);
}
@@ -100,6 +116,18 @@ public class NewJREUtil {
nearestInternalRuntime, nearestInstalledRuntime, (value)->value.rank
);
// Check if the selected runtime actually exists in the APK, else download it
// If it isn't InternalRuntime then it wasn't in the apk in the first place!
if (selectedRankedRuntime.value instanceof InternalRuntime)
if (!checkInternalRuntime(assetManager, (InternalRuntime) selectedRankedRuntime.value)) {
if (nearestInstalledRuntime == null) // If this was non-null then it would be a valid runtime and we can leave it be
tryDownloadRuntime(activity, gameRequiredVersion);
// This means the internal runtime didn't extract so let's use installed instead
// This also refreshes it so after the runtime download, it can find the new runtime
selectedRankedRuntime = getNearestInstalledRuntime(gameRequiredVersion);
}
// No possible selections
if(selectedRankedRuntime == null) {
showRuntimeFail(activity, versionInfo);
@@ -141,6 +169,46 @@ public class NewJREUtil {
activity.getString(R.string.multirt_nocompatiblert, verInfo.javaVersion.majorVersion));
}
public static boolean isValidJavaVersion(int version) {
for (InternalRuntime javaVersion : InternalRuntime.values()) {
if (javaVersion.majorVersion == version) {
return true;
}
}
return false;
}
private static String getJreSource(int javaVersion, String arch){
return String.format("https://github.com/AngelAuraMC/angelauramc-openjdk-build/releases/latest/download/jre%s-android-%s.tar.xz", javaVersion, arch);
}
/**
* @return whether installation was successful or not
*/
private static boolean tryDownloadRuntime(Activity activity, int gameRequiredVersion){
if (!isOnline(activity)) return false;
String arch = archAsString(getDeviceArchitecture());
if (!isValidJavaVersion(gameRequiredVersion)) return false;
try {
File outputFile = new File(Tools.DIR_CACHE, String.format("jre%s-android-%s.tar.xz", gameRequiredVersion, arch));
DownloaderProgressWrapper monitor = new DownloaderProgressWrapper(R.string.newdl_downloading_jre_runtime,
ProgressLayout.UNPACK_RUNTIME);
monitor.extraString = Integer.toString(gameRequiredVersion);
DownloadUtils.downloadFileMonitored(
getJreSource(gameRequiredVersion, arch),
outputFile,
null,
monitor
);
String jreName = "External-" + gameRequiredVersion;
MultiRTUtils.installRuntimeNamed(NATIVE_LIB_DIR, new FileInputStream(outputFile), jreName);
MultiRTUtils.postPrepare(jreName);
outputFile.delete();
} catch (IOException e) {
throw new RuntimeException("Failed to download Java "+gameRequiredVersion+" for "+arch, e);
}
return true;
}
private enum InternalRuntime {
JRE_17(17, "Internal-17", "components/jre-new"),
JRE_21(21, "Internal-21", "components/jre-21"),

View File

@@ -141,9 +141,7 @@ public class MinecraftDownloader {
mDownloaderThreadException = new AtomicReference<>(null);
mUseFileCounter = false;
if(!downloadAndProcessMetadata(activity, verInfo, versionName)) {
throw new RuntimeException(activity.getString(R.string.exception_failed_to_unpack_jre17));
}
downloadAndProcessMetadata(activity, verInfo, versionName);
ArrayBlockingQueue<Runnable> taskQueue =
new ArrayBlockingQueue<>(mScheduledDownloadTasks.size(), false);
@@ -293,7 +291,7 @@ public class MinecraftDownloader {
}
if(activity != null && !NewJREUtil.installNewJreIfNeeded(activity, verInfo)){
return false;
throw new RuntimeException(activity.getString(R.string.exception_failed_to_unpack_jre17));
}
JAssets assets = downloadAssetsIndex(verInfo);

View File

@@ -381,6 +381,7 @@
<string name="preference_vsync_in_zink_description">Allows the launcher to use internal system APIs to enable V-Sync for Zink. Turn this off if your launcher suddenly crashes with Zink after a system update.</string>
<string name="exception_failed_to_unpack_jre17">Failed to install JRE 17</string>
<string name="newdl_starting">Reading game metadata…</string>
<string name="newdl_downloading_jre_runtime">Downloading Java %s runtime (%.2f/%.2f MB)</string>
<string name="newdl_downloading_metadata">Downloading game metadata (%s)</string>
<string name="newdl_downloading_game_files">Downloading game… (%d/%d, %.2f MB/s)</string>
<string name="newdl_downloading_game_files_size">Downloading game… (%.2f/%.2f MB, %.2f MB/s)</string>