Loading core/java/android/content/res/Resources.java +98 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.graphics.drawable.Drawable.ConstantState; import android.graphics.drawable.DrawableInflater; import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AttributeSet; Loading Loading @@ -132,6 +133,11 @@ public class Resources { private static final Object sSync = new Object(); private final Object mUpdateLock = new Object(); /** * Controls whether we should preload resources during zygote init. */ private static final boolean PRELOAD_RESOURCES = true; // Used by BridgeResources in layoutlib @UnsupportedAppUsage static Resources mSystem = null; Loading Loading @@ -2666,6 +2672,98 @@ public class Resources { } } /** * Load in commonly used resources, so they can be shared across processes. * * These tend to be a few Kbytes, but are frequently in the 20-40K range, and occasionally even * larger. * @hide */ @UnsupportedAppUsage public static void preloadResources() { try { final Resources sysRes = Resources.getSystem(); sysRes.startPreloading(); if (PRELOAD_RESOURCES) { Log.i(TAG, "Preloading resources..."); long startTime = SystemClock.uptimeMillis(); TypedArray ar = sysRes.obtainTypedArray( com.android.internal.R.array.preloaded_drawables); int numberOfEntries = preloadDrawables(sysRes, ar); ar.recycle(); Log.i(TAG, "...preloaded " + numberOfEntries + " resources in " + (SystemClock.uptimeMillis() - startTime) + "ms."); startTime = SystemClock.uptimeMillis(); ar = sysRes.obtainTypedArray( com.android.internal.R.array.preloaded_color_state_lists); numberOfEntries = preloadColorStateLists(sysRes, ar); ar.recycle(); Log.i(TAG, "...preloaded " + numberOfEntries + " resources in " + (SystemClock.uptimeMillis() - startTime) + "ms."); if (sysRes.getBoolean( com.android.internal.R.bool.config_freeformWindowManagement)) { startTime = SystemClock.uptimeMillis(); ar = sysRes.obtainTypedArray( com.android.internal.R.array.preloaded_freeform_multi_window_drawables); numberOfEntries = preloadDrawables(sysRes, ar); ar.recycle(); Log.i(TAG, "...preloaded " + numberOfEntries + " resource in " + (SystemClock.uptimeMillis() - startTime) + "ms."); } } sysRes.finishPreloading(); } catch (RuntimeException e) { Log.w(TAG, "Failure preloading resources", e); } } private static int preloadColorStateLists(Resources resources, TypedArray ar) { final int numberOfEntries = ar.length(); for (int i = 0; i < numberOfEntries; i++) { int id = ar.getResourceId(i, 0); if (id != 0) { if (resources.getColorStateList(id, null) == null) { throw new IllegalArgumentException( "Unable to find preloaded color resource #0x" + Integer.toHexString(id) + " (" + ar.getString(i) + ")"); } } } return numberOfEntries; } private static int preloadDrawables(Resources resources, TypedArray ar) { final int numberOfEntries = ar.length(); for (int i = 0; i < numberOfEntries; i++) { int id = ar.getResourceId(i, 0); if (id != 0) { if (resources.getDrawable(id, null) == null) { throw new IllegalArgumentException( "Unable to find preloaded drawable resource #0x" + Integer.toHexString(id) + " (" + ar.getString(i) + ")"); } } } return numberOfEntries; } /** * Clear the cache when the framework resources packages is changed. * @hide */ @VisibleForTesting public static void resetPreloadDrawableStateCache() { ResourcesImpl.resetDrawableStateCache(); preloadResources(); } /** @hide */ public void dump(PrintWriter pw, String prefix) { pw.println(prefix + "class=" + getClass()); Loading core/java/android/content/res/ResourcesImpl.java +18 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import android.util.TypedValue; import android.util.Xml; import android.view.DisplayAdjustments; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.GrowingArrayUtils; import libcore.util.NativeAllocationRegistry; Loading Loading @@ -158,6 +159,23 @@ public class ResourcesImpl { sPreloadedDrawables[1] = new LongSparseArray<>(); } /** * Clear the cache when the framework resources packages is changed. * * It's only used in the test initial function instead of regular app behaviors. It doesn't * guarantee the thread-safety so mark this with @VisibleForTesting. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) static void resetDrawableStateCache() { synchronized (sSync) { sPreloadedDrawables[0].clear(); sPreloadedDrawables[1].clear(); sPreloadedColorDrawables.clear(); sPreloadedComplexColors.clear(); sPreloaded = false; } } /** * Creates a new ResourcesImpl object with CompatibilityInfo. * Loading core/java/com/android/internal/os/ZygoteInit.java +1 −94 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import android.app.ApplicationLoaders; import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.SharedLibraryInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.os.Build; import android.os.Environment; import android.os.IInstalld; Loading Loading @@ -101,22 +100,11 @@ public class ZygoteInit { // --usap-socket-name parameter. private static final String SOCKET_NAME_ARG = "--socket-name="; /** * Used to pre-load resources. */ @UnsupportedAppUsage private static Resources mResources; /** * The path of a file that contains classes to preload. */ private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes"; /** * Controls whether we should preload resources during zygote init. */ private static final boolean PRELOAD_RESOURCES = true; private static final int UNPRIVILEGED_UID = 9999; private static final int UNPRIVILEGED_GID = 9999; Loading @@ -143,7 +131,7 @@ public class ZygoteInit { cacheNonBootClasspathClassLoaders(); bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders bootTimingsTraceLog.traceBegin("PreloadResources"); preloadResources(); Resources.preloadResources(); bootTimingsTraceLog.traceEnd(); // PreloadResources Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs"); nativePreloadAppProcessHALs(); Loading Loading @@ -413,87 +401,6 @@ public class ZygoteInit { }); } /** * Load in commonly used resources, so they can be shared across processes. * * These tend to be a few Kbytes, but are frequently in the 20-40K range, and occasionally even * larger. */ private static void preloadResources() { try { mResources = Resources.getSystem(); mResources.startPreloading(); if (PRELOAD_RESOURCES) { Log.i(TAG, "Preloading resources..."); long startTime = SystemClock.uptimeMillis(); TypedArray ar = mResources.obtainTypedArray( com.android.internal.R.array.preloaded_drawables); int N = preloadDrawables(ar); ar.recycle(); Log.i(TAG, "...preloaded " + N + " resources in " + (SystemClock.uptimeMillis() - startTime) + "ms."); startTime = SystemClock.uptimeMillis(); ar = mResources.obtainTypedArray( com.android.internal.R.array.preloaded_color_state_lists); N = preloadColorStateLists(ar); ar.recycle(); Log.i(TAG, "...preloaded " + N + " resources in " + (SystemClock.uptimeMillis() - startTime) + "ms."); if (mResources.getBoolean( com.android.internal.R.bool.config_freeformWindowManagement)) { startTime = SystemClock.uptimeMillis(); ar = mResources.obtainTypedArray( com.android.internal.R.array.preloaded_freeform_multi_window_drawables); N = preloadDrawables(ar); ar.recycle(); Log.i(TAG, "...preloaded " + N + " resource in " + (SystemClock.uptimeMillis() - startTime) + "ms."); } } mResources.finishPreloading(); } catch (RuntimeException e) { Log.w(TAG, "Failure preloading resources", e); } } private static int preloadColorStateLists(TypedArray ar) { int N = ar.length(); for (int i = 0; i < N; i++) { int id = ar.getResourceId(i, 0); if (id != 0) { if (mResources.getColorStateList(id, null) == null) { throw new IllegalArgumentException( "Unable to find preloaded color resource #0x" + Integer.toHexString(id) + " (" + ar.getString(i) + ")"); } } } return N; } private static int preloadDrawables(TypedArray ar) { int N = ar.length(); for (int i = 0; i < N; i++) { int id = ar.getResourceId(i, 0); if (id != 0) { if (mResources.getDrawable(id, null) == null) { throw new IllegalArgumentException( "Unable to find preloaded drawable resource #0x" + Integer.toHexString(id) + " (" + ar.getString(i) + ")"); } } } return N; } /** * Runs several special GCs to try to clean up a few generations of softly- and final-reachable * objects, along with any other garbage. This is only useful just before a fork(). Loading Loading
core/java/android/content/res/Resources.java +98 −0 Original line number Diff line number Diff line Loading @@ -53,6 +53,7 @@ import android.graphics.drawable.Drawable.ConstantState; import android.graphics.drawable.DrawableInflater; import android.os.Build; import android.os.Bundle; import android.os.SystemClock; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AttributeSet; Loading Loading @@ -132,6 +133,11 @@ public class Resources { private static final Object sSync = new Object(); private final Object mUpdateLock = new Object(); /** * Controls whether we should preload resources during zygote init. */ private static final boolean PRELOAD_RESOURCES = true; // Used by BridgeResources in layoutlib @UnsupportedAppUsage static Resources mSystem = null; Loading Loading @@ -2666,6 +2672,98 @@ public class Resources { } } /** * Load in commonly used resources, so they can be shared across processes. * * These tend to be a few Kbytes, but are frequently in the 20-40K range, and occasionally even * larger. * @hide */ @UnsupportedAppUsage public static void preloadResources() { try { final Resources sysRes = Resources.getSystem(); sysRes.startPreloading(); if (PRELOAD_RESOURCES) { Log.i(TAG, "Preloading resources..."); long startTime = SystemClock.uptimeMillis(); TypedArray ar = sysRes.obtainTypedArray( com.android.internal.R.array.preloaded_drawables); int numberOfEntries = preloadDrawables(sysRes, ar); ar.recycle(); Log.i(TAG, "...preloaded " + numberOfEntries + " resources in " + (SystemClock.uptimeMillis() - startTime) + "ms."); startTime = SystemClock.uptimeMillis(); ar = sysRes.obtainTypedArray( com.android.internal.R.array.preloaded_color_state_lists); numberOfEntries = preloadColorStateLists(sysRes, ar); ar.recycle(); Log.i(TAG, "...preloaded " + numberOfEntries + " resources in " + (SystemClock.uptimeMillis() - startTime) + "ms."); if (sysRes.getBoolean( com.android.internal.R.bool.config_freeformWindowManagement)) { startTime = SystemClock.uptimeMillis(); ar = sysRes.obtainTypedArray( com.android.internal.R.array.preloaded_freeform_multi_window_drawables); numberOfEntries = preloadDrawables(sysRes, ar); ar.recycle(); Log.i(TAG, "...preloaded " + numberOfEntries + " resource in " + (SystemClock.uptimeMillis() - startTime) + "ms."); } } sysRes.finishPreloading(); } catch (RuntimeException e) { Log.w(TAG, "Failure preloading resources", e); } } private static int preloadColorStateLists(Resources resources, TypedArray ar) { final int numberOfEntries = ar.length(); for (int i = 0; i < numberOfEntries; i++) { int id = ar.getResourceId(i, 0); if (id != 0) { if (resources.getColorStateList(id, null) == null) { throw new IllegalArgumentException( "Unable to find preloaded color resource #0x" + Integer.toHexString(id) + " (" + ar.getString(i) + ")"); } } } return numberOfEntries; } private static int preloadDrawables(Resources resources, TypedArray ar) { final int numberOfEntries = ar.length(); for (int i = 0; i < numberOfEntries; i++) { int id = ar.getResourceId(i, 0); if (id != 0) { if (resources.getDrawable(id, null) == null) { throw new IllegalArgumentException( "Unable to find preloaded drawable resource #0x" + Integer.toHexString(id) + " (" + ar.getString(i) + ")"); } } } return numberOfEntries; } /** * Clear the cache when the framework resources packages is changed. * @hide */ @VisibleForTesting public static void resetPreloadDrawableStateCache() { ResourcesImpl.resetDrawableStateCache(); preloadResources(); } /** @hide */ public void dump(PrintWriter pw, String prefix) { pw.println(prefix + "class=" + getClass()); Loading
core/java/android/content/res/ResourcesImpl.java +18 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ import android.util.TypedValue; import android.util.Xml; import android.view.DisplayAdjustments; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.GrowingArrayUtils; import libcore.util.NativeAllocationRegistry; Loading Loading @@ -158,6 +159,23 @@ public class ResourcesImpl { sPreloadedDrawables[1] = new LongSparseArray<>(); } /** * Clear the cache when the framework resources packages is changed. * * It's only used in the test initial function instead of regular app behaviors. It doesn't * guarantee the thread-safety so mark this with @VisibleForTesting. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) static void resetDrawableStateCache() { synchronized (sSync) { sPreloadedDrawables[0].clear(); sPreloadedDrawables[1].clear(); sPreloadedColorDrawables.clear(); sPreloadedComplexColors.clear(); sPreloaded = false; } } /** * Creates a new ResourcesImpl object with CompatibilityInfo. * Loading
core/java/com/android/internal/os/ZygoteInit.java +1 −94 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import android.app.ApplicationLoaders; import android.compat.annotation.UnsupportedAppUsage; import android.content.pm.SharedLibraryInfo; import android.content.res.Resources; import android.content.res.TypedArray; import android.os.Build; import android.os.Environment; import android.os.IInstalld; Loading Loading @@ -101,22 +100,11 @@ public class ZygoteInit { // --usap-socket-name parameter. private static final String SOCKET_NAME_ARG = "--socket-name="; /** * Used to pre-load resources. */ @UnsupportedAppUsage private static Resources mResources; /** * The path of a file that contains classes to preload. */ private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes"; /** * Controls whether we should preload resources during zygote init. */ private static final boolean PRELOAD_RESOURCES = true; private static final int UNPRIVILEGED_UID = 9999; private static final int UNPRIVILEGED_GID = 9999; Loading @@ -143,7 +131,7 @@ public class ZygoteInit { cacheNonBootClasspathClassLoaders(); bootTimingsTraceLog.traceEnd(); // CacheNonBootClasspathClassLoaders bootTimingsTraceLog.traceBegin("PreloadResources"); preloadResources(); Resources.preloadResources(); bootTimingsTraceLog.traceEnd(); // PreloadResources Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadAppProcessHALs"); nativePreloadAppProcessHALs(); Loading Loading @@ -413,87 +401,6 @@ public class ZygoteInit { }); } /** * Load in commonly used resources, so they can be shared across processes. * * These tend to be a few Kbytes, but are frequently in the 20-40K range, and occasionally even * larger. */ private static void preloadResources() { try { mResources = Resources.getSystem(); mResources.startPreloading(); if (PRELOAD_RESOURCES) { Log.i(TAG, "Preloading resources..."); long startTime = SystemClock.uptimeMillis(); TypedArray ar = mResources.obtainTypedArray( com.android.internal.R.array.preloaded_drawables); int N = preloadDrawables(ar); ar.recycle(); Log.i(TAG, "...preloaded " + N + " resources in " + (SystemClock.uptimeMillis() - startTime) + "ms."); startTime = SystemClock.uptimeMillis(); ar = mResources.obtainTypedArray( com.android.internal.R.array.preloaded_color_state_lists); N = preloadColorStateLists(ar); ar.recycle(); Log.i(TAG, "...preloaded " + N + " resources in " + (SystemClock.uptimeMillis() - startTime) + "ms."); if (mResources.getBoolean( com.android.internal.R.bool.config_freeformWindowManagement)) { startTime = SystemClock.uptimeMillis(); ar = mResources.obtainTypedArray( com.android.internal.R.array.preloaded_freeform_multi_window_drawables); N = preloadDrawables(ar); ar.recycle(); Log.i(TAG, "...preloaded " + N + " resource in " + (SystemClock.uptimeMillis() - startTime) + "ms."); } } mResources.finishPreloading(); } catch (RuntimeException e) { Log.w(TAG, "Failure preloading resources", e); } } private static int preloadColorStateLists(TypedArray ar) { int N = ar.length(); for (int i = 0; i < N; i++) { int id = ar.getResourceId(i, 0); if (id != 0) { if (mResources.getColorStateList(id, null) == null) { throw new IllegalArgumentException( "Unable to find preloaded color resource #0x" + Integer.toHexString(id) + " (" + ar.getString(i) + ")"); } } } return N; } private static int preloadDrawables(TypedArray ar) { int N = ar.length(); for (int i = 0; i < N; i++) { int id = ar.getResourceId(i, 0); if (id != 0) { if (mResources.getDrawable(id, null) == null) { throw new IllegalArgumentException( "Unable to find preloaded drawable resource #0x" + Integer.toHexString(id) + " (" + ar.getString(i) + ")"); } } } return N; } /** * Runs several special GCs to try to clean up a few generations of softly- and final-reachable * objects, along with any other garbage. This is only useful just before a fork(). Loading