From 12587227c11574824603dbca8091626c7a534cb2 Mon Sep 17 00:00:00 2001 From: Oskar Eichler Date: Mon, 31 Aug 2026 13:16:51 +0300 Subject: [PATCH] fix(Android): close temporary image and theme resources --- .../react/modal/ModalViewManager.kt | 6 ++++- .../utils/ImageLoader.kt | 15 +++++++---- .../utils/ImageLoaderTest.kt | 26 +++++++++++++++++++ 3 files changed, 41 insertions(+), 6 deletions(-) create mode 100644 android/src/test/java/com/reactnativenavigation/utils/ImageLoaderTest.kt diff --git a/android/src/main/java/com/reactnativenavigation/react/modal/ModalViewManager.kt b/android/src/main/java/com/reactnativenavigation/react/modal/ModalViewManager.kt index 2ab4afcd71e..b2f27186ecf 100644 --- a/android/src/main/java/com/reactnativenavigation/react/modal/ModalViewManager.kt +++ b/android/src/main/java/com/reactnativenavigation/react/modal/ModalViewManager.kt @@ -121,7 +121,11 @@ private fun getModalHostSize(activity: Activity): Point { val attrs = intArrayOf(android.R.attr.windowFullscreen) val theme = activity.theme val ta = theme.obtainStyledAttributes(attrs) - val windowFullscreen = ta.getBoolean(0, false) + val windowFullscreen = try { + ta.getBoolean(0, false) + } finally { + ta.recycle() + } // We need to add the status bar height to the height if we have a fullscreen window, // because Display.getCurrentSizeRange doesn't include it. diff --git a/android/src/main/java/com/reactnativenavigation/utils/ImageLoader.kt b/android/src/main/java/com/reactnativenavigation/utils/ImageLoader.kt index f9d4b18160b..695ddedec75 100644 --- a/android/src/main/java/com/reactnativenavigation/utils/ImageLoader.kt +++ b/android/src/main/java/com/reactnativenavigation/utils/ImageLoader.kt @@ -77,10 +77,15 @@ open class ImageLoader { @Throws(IOException::class) private fun readJsDevImage(context: Context, source: String): Drawable { val threadPolicy = adjustThreadPolicyDebug(context) - val `is` = openStream(context, source) - val bitmap = BitmapFactory.decodeStream(`is`) - restoreThreadPolicyDebug(context, threadPolicy) - return BitmapDrawable(context.resources, bitmap) + try { + val stream = openStream(context, source) + ?: throw FileNotFoundException("Could not open image $source") + val bitmap = stream.use(BitmapFactory::decodeStream) + ?: throw IOException("Could not decode image $source") + return BitmapDrawable(context.resources, bitmap) + } finally { + restoreThreadPolicyDebug(context, threadPolicy) + } } private fun isLocalFile(uri: Uri): Boolean { @@ -128,4 +133,4 @@ open class ImageLoader { return context.contentResolver.openInputStream(Uri.parse(uri)) } } -} \ No newline at end of file +} diff --git a/android/src/test/java/com/reactnativenavigation/utils/ImageLoaderTest.kt b/android/src/test/java/com/reactnativenavigation/utils/ImageLoaderTest.kt new file mode 100644 index 00000000000..dccaa05ee5a --- /dev/null +++ b/android/src/test/java/com/reactnativenavigation/utils/ImageLoaderTest.kt @@ -0,0 +1,26 @@ +package com.reactnativenavigation.utils + +import android.os.StrictMode +import com.reactnativenavigation.BaseTest +import org.junit.Assert.assertEquals +import org.junit.Test +import org.mockito.kotlin.mock + +class ImageLoaderTest : BaseTest() { + @Test + fun failedDevImageLoadRestoresThreadPolicy() { + val originalPolicy = StrictMode.ThreadPolicy.Builder() + .detectNetwork() + .penaltyLog() + .build() + StrictMode.setThreadPolicy(originalPolicy) + + ImageLoader().loadIcon( + newActivity(), + "content://missing/image", + mock() + ) + + assertEquals(originalPolicy.toString(), StrictMode.getThreadPolicy().toString()) + } +}