From bca127132955bcf965412546c31eb1ba840dfd5b Mon Sep 17 00:00:00 2001 From: Manol Donev Date: Thu, 14 Nov 2019 14:22:20 +0200 Subject: [PATCH] fix(android): Fatal Exception: java.lang.OutOfMemoryError (#8061) (#8098) Crashlytics: **Async.java line 181** **org.nativescript.widgets.Async$Image$DownloadImageTask.doInBackground** ``` Fatal Exception: java.lang.OutOfMemoryError: Failed to allocate a 3601932 byte allocation with 970044 free bytes and 947KB until OOM at dalvik.system.VMRuntime.newNonMovableArray(VMRuntime.java) at android.graphics.BitmapFactory.nativeDecodeStream(BitmapFactory.java) at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:863) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:839) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:877) at org.nativescript.widgets.Async$Image$DownloadImageTask.doInBackground(Async.java:181) at org.nativescript.widgets.Async$Image$4.run(Async.java:157) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at org.nativescript.widgets.Async$PriorityThreadFactory$1.run(Async.java:86) at java.lang.Thread.run(Thread.java:818) ``` Crashlytics **Async.java line 473** **org.nativescript.widgets.Async$Http$RequestResult.readResponseStream** ``` Fatal Exception: java.lang.OutOfMemoryError: Failed to allocate a 3000012 byte allocation with 2043950 free bytes and 1996KB until OOM at dalvik.system.VMRuntime.newNonMovableArray(VMRuntime.java) at android.graphics.BitmapFactory.nativeDecodeByteArray(BitmapFactory.java) at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:744) at org.nativescript.widgets.Async$Http$RequestResult.readResponseStream(Async.java:473) at org.nativescript.widgets.Async$Http$HttpRequestTask.doInBackground(Async.java:555) at org.nativescript.widgets.Async$Http$1.run(Async.java:307) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at org.nativescript.widgets.Async$PriorityThreadFactory$1.run(Async.java:86) at java.lang.Thread.run(Thread.java:818) ``` ## PR Checklist - [x] The PR title follows our guidelines: https://github.com/NativeScript/NativeScript/blob/master/CONTRIBUTING.md#commit-messages. - [x] There is an issue for the bug/feature this PR is for. To avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it. - [x] You have signed the [CLA](http://www.nativescript.org/cla). - [x] All existing tests are passing: https://github.com/NativeScript/NativeScript/blob/master/DevelopmentWorkflow.md#running-unit-tests. - [ ] Tests for the changes are included - https://github.com/NativeScript/NativeScript/blob/master/WritingUnitTests.md. ## What is the current behavior? Uncaught exception resulting in crash. This was introduced in v6.2.0. ## What is the new behavior? Additional `catch` block for uncaught exception type `OutOfMemoryError` Fixes: https://www.telerik.com/account/support-tickets/view-ticket/1436458 --- .../src/main/java/org/nativescript/widgets/Async.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/Async.java b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/Async.java index 265a905ce..9aa553f00 100644 --- a/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/Async.java +++ b/tns-core-modules-widgets/android/widgets/src/main/java/org/nativescript/widgets/Async.java @@ -180,11 +180,8 @@ public class Async { stream = new java.net.URL(params[0]).openStream(); Bitmap bmp = BitmapFactory.decodeStream(stream); return bmp; - } catch (MalformedURLException e) { - Log.e(TAG, "Failed to decode stream, MalformedURLException: " + e.getMessage()); - return null; - } catch (IOException e) { - Log.e(TAG, "Failed to decode stream, IOException: " + e.getMessage()); + } catch (Throwable t) { + Log.e(TAG, "Failed to decode stream, Throwable: " + t.getMessage()); return null; } finally { if (stream != null) { @@ -472,8 +469,8 @@ public class Async { bitmapOptions.inSampleSize = scale; this.responseAsImage = BitmapFactory.decodeByteArray(responseStream.buf(), 0, responseStream.size(), bitmapOptions); } - } catch (Exception e) { - Log.e(TAG, "Failed to decode byte array, Exception: " + e.getMessage()); + } catch (Throwable t) { + Log.e(TAG, "Failed to decode byte array, Throwable: " + t.getMessage()); } if (this.responseAsImage == null) {