From 66f65f04d23d7ce4fe4a5f00cd081ee8fb3a737b Mon Sep 17 00:00:00 2001 From: SerpentSpirale Date: Mon, 6 Sep 2021 19:21:52 +0200 Subject: [PATCH] Reduce ControlButton instantiation memory usage --- .../customcontrols/ControlData.java | 69 +++++++++++++++---- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java index 0c3938fb9..204f431ad 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/ControlData.java @@ -1,6 +1,10 @@ package net.kdt.pojavlaunch.customcontrols; import android.util.*; + +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.*; import net.kdt.pojavlaunch.*; import net.kdt.pojavlaunch.prefs.LauncherPreferences; @@ -28,7 +32,14 @@ public class ControlData { // Internal usage only public boolean isHideable; - + + private static WeakReference builder; + private static WeakReference expression; + static { + bypassExpressionBuilder(); + } + + /** * Both fields below are dynamic position data, auto updates * X and Y position, unlike the original one which uses fixed @@ -188,20 +199,9 @@ public class ControlData { } private static float calculate(String math) { - return (float) new ExpressionBuilder(math) - .function(new Function("dp", 1) { - @Override - public double apply(double... args) { - return Tools.pxToDp((float) args[0]); - } - }) - .function(new Function("px", 1) { - @Override - public double apply(double... args) { - return Tools.dpToPx((float) args[0]); - } - }) - .build().evaluate(); + setExpression(math); + if(builder.get() == null) bypassExpressionBuilder(); + return (float) builder.get().build().evaluate(); } private static int[] inflateKeycodeArray(int[] keycodes){ @@ -236,4 +236,43 @@ public class ControlData { public void setHeight(float heightInPx){ height = Tools.pxToDp(heightInPx); } + + /** + * Create a weak reference to a builder and its expression field. + * Although VERY bad practice it isn't slower due to saved GC time. + * The normal way requires us to create ONE builder and TWO functions for EACH button. + */ + private static void bypassExpressionBuilder(){ + ExpressionBuilder expressionBuilder = new ExpressionBuilder("1 + 1") + .function(new Function("dp", 1) { + @Override + public double apply(double... args) { + return Tools.pxToDp((float) args[0]); + } + }) + .function(new Function("px", 1) { + @Override + public double apply(double... args) { + return Tools.dpToPx((float) args[0]); + } + }); + builder = new WeakReference<>(expressionBuilder); + try { + expression = new WeakReference<>(builder.get().getClass().getDeclaredField("expression")); + expression.get().setAccessible(true); + expression.get().set(expression.get(), expression.get().getModifiers() & ~Modifier.FINAL); + }catch (Exception ignored){} + } + + /** + * wrapper for the WeakReference to the expressionField. + * @param stringExpression the expression to set. + */ + private static void setExpression(String stringExpression){ + try { + expression.get().set(builder.get(), (String) stringExpression); + }catch (IllegalAccessException e){} + } + + }