From 0858d4120df242196570f5394f8ae4e623533493 Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Tue, 21 Jul 2020 11:12:20 +0200 Subject: [PATCH 01/12] Fix Drawable Runtime - More Info in Description The AppCompat Theme Theme.AppCompat.Light.NoActionBar provides a default Drawable resource for AppCompatEditText. The resource is located in @drawable/abc_edit_text_material.xml https://chromium.googlesource.com/android_tools/+/7200281446186c7192cb02f54dc2b38e02d705e5/sdk/extras/android/support/v7/appcompat/res/drawable/abc_edit_text_material.xml A Runtime Error is triggered in a scenario with the following conditions: 1) Rendering a large number of TextInputs in the screen with a key prop 2) Triggering re-render with setInterval The scenario is also experienced with FlatList and ONLY using TextInput component. The following Runtime Error is triggered: NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources) It is caused from the following line from abc_edit_text_material.xml I posted a Minimal Reproducible Example at https://github.com/facebook/react-native/issues/17530#issuecomment-660017858 This commit simply changes RNTester to use a custom drawable resource for TextInput named @drawable/edit_text. --- .../android/app/src/main/AndroidManifest.xml | 2 +- .../app/src/main/res/drawable/edit_text.xml | 28 +++++++++++++++++++ .../app/src/main/res/values/styles.xml | 4 +-- 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 RNTester/android/app/src/main/res/drawable/edit_text.xml diff --git a/RNTester/android/app/src/main/AndroidManifest.xml b/RNTester/android/app/src/main/AndroidManifest.xml index d47ee519ae3180..83b69d1f4ad42d 100644 --- a/RNTester/android/app/src/main/AndroidManifest.xml +++ b/RNTester/android/app/src/main/AndroidManifest.xml @@ -30,7 +30,7 @@ android:banner="@drawable/tv_banner" android:icon="@drawable/launcher_icon" android:label="@string/app_name" - android:theme="@style/Theme.ReactNative.AppCompat.Light" > + android:theme="@style/AppTheme"> + + + + + + + + + + diff --git a/RNTester/android/app/src/main/res/values/styles.xml b/RNTester/android/app/src/main/res/values/styles.xml index 62fe59fa485459..e0800ee36e0c58 100644 --- a/RNTester/android/app/src/main/res/values/styles.xml +++ b/RNTester/android/app/src/main/res/values/styles.xml @@ -1,9 +1,9 @@ - - + From 4a414e2cc7e17068da26ef7727a04d0aa5883a17 Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Tue, 21 Jul 2020 12:12:35 +0200 Subject: [PATCH 02/12] RNTester Minimum Reproducible Example A Minimum Reproducible Example that triggers the Null Pointer Exception Runtime Error NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)' The following are the conditions that trigger the runtime error: 1) a large list (>100) TextInputs with key prop 2) with FlatList passing prop data=[{key: 1, key:2,.., key:5000]] 3) trigger re-render to ensure the NPE Runtime Error is triggered The example is built using hooks useEffect similar to componentDidMount. Original post is here https://github.com/facebook/react-native/issues/17530#issuecomment-660017858 --- .../js/examples/TextInput/TextInputKeyProp.js | 61 +++++++++++++++++++ RNTester/js/utils/RNTesterList.android.js | 4 ++ 2 files changed, 65 insertions(+) create mode 100644 RNTester/js/examples/TextInput/TextInputKeyProp.js diff --git a/RNTester/js/examples/TextInput/TextInputKeyProp.js b/RNTester/js/examples/TextInput/TextInputKeyProp.js new file mode 100644 index 00000000000000..6b5b3cd8c5298f --- /dev/null +++ b/RNTester/js/examples/TextInput/TextInputKeyProp.js @@ -0,0 +1,61 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + * @flow + */ + +'use strict'; + +const React = require('react'); +const {View, TextInput} = require('react-native'); +const {useEffect, useState} = React; + +function TextInputKeyProp() { + const [startKey, setStartKey] = useState(0); + + const updateKey = () => { + setStartKey({ + startKey: startKey + 100 + }); + }; + + useEffect(() => { + const interval = setInterval(updateKey, 3000); + return () => clearInterval(interval); + }, []) + + const textInputs = []; + for (let i = 0; i < 1000; i++) { + const key = (startKey + i).toString(); + console.log("key", key); + // REMOVE KEY PROP TO FIX THIS + textInputs.push( + + ); + } + + return ( + + { textInputs } + + ); +} + +exports.title = ''; +exports.description = 'Periodically render large number of TextInputs with key prop without a Runtime Error'; +exports.examples = [ + { + title: 'A list of TextInputs with key prop - Re-render every 3 seconds', + description: + 'A list of TextInputs with key prop re-rendered every 3 seconds will trigger an NPE Runtime error.', + render: function(): React.Node { + return ; + }, + }, +]; diff --git a/RNTester/js/utils/RNTesterList.android.js b/RNTester/js/utils/RNTesterList.android.js index 2b1b921efe75f0..e734798120873b 100644 --- a/RNTester/js/utils/RNTesterList.android.js +++ b/RNTester/js/utils/RNTesterList.android.js @@ -101,6 +101,10 @@ const ComponentExamples: Array = [ key: 'TextInputExample', module: require('../examples/TextInput/TextInputExample'), }, + { + key: 'TextInputs with key prop', + module: require('../examples/TextInput/TextInputKeyProp'), + }, { key: 'TouchableExample', module: require('../examples/Touchable/TouchableExample'), From e488a410f76922c5fe4cda6391def5b3f901f2fe Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Tue, 21 Jul 2020 12:22:04 +0200 Subject: [PATCH 03/12] removing console.log from RNTester example --- RNTester/js/examples/TextInput/TextInputKeyProp.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/RNTester/js/examples/TextInput/TextInputKeyProp.js b/RNTester/js/examples/TextInput/TextInputKeyProp.js index 6b5b3cd8c5298f..06c82045f2a78e 100644 --- a/RNTester/js/examples/TextInput/TextInputKeyProp.js +++ b/RNTester/js/examples/TextInput/TextInputKeyProp.js @@ -31,8 +31,6 @@ function TextInputKeyProp() { const textInputs = []; for (let i = 0; i < 1000; i++) { const key = (startKey + i).toString(); - console.log("key", key); - // REMOVE KEY PROP TO FIX THIS textInputs.push( Date: Tue, 21 Jul 2020 12:25:02 +0200 Subject: [PATCH 04/12] remove line from file --- RNTester/android/app/src/main/res/drawable/edit_text.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/RNTester/android/app/src/main/res/drawable/edit_text.xml b/RNTester/android/app/src/main/res/drawable/edit_text.xml index 87038a91bbc483..40b9f49b2667c6 100644 --- a/RNTester/android/app/src/main/res/drawable/edit_text.xml +++ b/RNTester/android/app/src/main/res/drawable/edit_text.xml @@ -25,4 +25,3 @@ - From f3493083df5e1b157bbdaf18f97c59b7b0ad828c Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Tue, 21 Jul 2020 12:27:51 +0200 Subject: [PATCH 05/12] updating template with custom drawable - more info Adding the edit_text.xml custom drawable to the android template to fix Null Pointer Exception Runtime Error from https://github.com/facebook/react-native/issues/17530 The template will include the following settings in new reactnative applications, more info on the issue, the cause of the error and the solution in commit 0858d4120df242196570f5394f8ae4e623533493 --- .../app/src/main/res/drawable/edit_text.xml | 27 +++++++++++++++++++ .../app/src/main/res/values/styles.xml | 1 + 2 files changed, 28 insertions(+) create mode 100644 template/android/app/src/main/res/drawable/edit_text.xml diff --git a/template/android/app/src/main/res/drawable/edit_text.xml b/template/android/app/src/main/res/drawable/edit_text.xml new file mode 100644 index 00000000000000..40b9f49b2667c6 --- /dev/null +++ b/template/android/app/src/main/res/drawable/edit_text.xml @@ -0,0 +1,27 @@ + + + + + + + + + + diff --git a/template/android/app/src/main/res/values/styles.xml b/template/android/app/src/main/res/values/styles.xml index 9fab0be743760d..8db0ef4f20ec70 100644 --- a/template/android/app/src/main/res/values/styles.xml +++ b/template/android/app/src/main/res/values/styles.xml @@ -4,6 +4,7 @@ From a6d8c3ddddc999fa3aae0d7087052044c9fce506 Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Thu, 23 Jul 2020 11:49:38 +0200 Subject: [PATCH 06/12] fixing flow and eslint issues --- .../js/examples/TextInput/TextInputKeyProp.js | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/RNTester/js/examples/TextInput/TextInputKeyProp.js b/RNTester/js/examples/TextInput/TextInputKeyProp.js index 06c82045f2a78e..7478715bd49d48 100644 --- a/RNTester/js/examples/TextInput/TextInputKeyProp.js +++ b/RNTester/js/examples/TextInput/TextInputKeyProp.js @@ -17,41 +17,34 @@ const {useEffect, useState} = React; function TextInputKeyProp() { const [startKey, setStartKey] = useState(0); - const updateKey = () => { - setStartKey({ - startKey: startKey + 100 - }); - }; - useEffect(() => { - const interval = setInterval(updateKey, 3000); + const interval = setInterval(() => setStartKey(startKey + 100), 3000); return () => clearInterval(interval); - }, []) + }, [startKey]); const textInputs = []; - for (let i = 0; i < 1000; i++) { + for (let i = 0; i < 1001; i++) { const key = (startKey + i).toString(); + console.log('Adding a TextInput with key ' + key); textInputs.push( - + , ); } - return ( - - { textInputs } - - ); + return {textInputs}; } exports.title = ''; -exports.description = 'Periodically render large number of TextInputs with key prop without a Runtime Error'; +exports.description = + 'Periodically render large number of TextInputs with key prop without a Runtime Error'; exports.examples = [ { - title: 'A list of TextInputs with key prop - Re-render every 3 seconds', + title: 'Long List of TextInputs with key props', description: - 'A list of TextInputs with key prop re-rendered every 3 seconds will trigger an NPE Runtime error.', + '100 TextInputs are added every 3 seconds to the View. #29452 avoids a NPE Runtime Error. If you want to trigger the Runtime, change 101 to 1001 in RNTester/TextInputKeyProp.js and use an Emulator with 8GB of RAM. This example is only meant to verify no RuntimeError is triggered. To test TextInput functionalities use the example.', render: function(): React.Node { return ; }, From 07841870485b9843a96c108c65ca8950f95b3180 Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Thu, 23 Jul 2020 11:51:49 +0200 Subject: [PATCH 07/12] limit TextInput to 100 to avoid memory issues --- RNTester/js/examples/TextInput/TextInputKeyProp.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RNTester/js/examples/TextInput/TextInputKeyProp.js b/RNTester/js/examples/TextInput/TextInputKeyProp.js index 7478715bd49d48..20650ac08a9e65 100644 --- a/RNTester/js/examples/TextInput/TextInputKeyProp.js +++ b/RNTester/js/examples/TextInput/TextInputKeyProp.js @@ -23,7 +23,7 @@ function TextInputKeyProp() { }, [startKey]); const textInputs = []; - for (let i = 0; i < 1001; i++) { + for (let i = 0; i < 101; i++) { const key = (startKey + i).toString(); console.log('Adding a TextInput with key ' + key); textInputs.push( From 73ffe6924732d4e0e0808d22babb35dd5ae72d5f Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Wed, 15 Sep 2021 09:07:44 +0800 Subject: [PATCH 08/12] rename edit_text drawable to rn_edit_text_material --- .../res/drawable/{edit_text.xml => rn_edit_text_material.xml} | 0 packages/rn-tester/android/app/src/main/res/values/styles.xml | 2 +- .../res/drawable/{edit_text.xml => rn_edit_text_material.xml} | 0 template/android/app/src/main/res/values/styles.xml | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename packages/rn-tester/android/app/src/main/res/drawable/{edit_text.xml => rn_edit_text_material.xml} (100%) rename template/android/app/src/main/res/drawable/{edit_text.xml => rn_edit_text_material.xml} (100%) diff --git a/packages/rn-tester/android/app/src/main/res/drawable/edit_text.xml b/packages/rn-tester/android/app/src/main/res/drawable/rn_edit_text_material.xml similarity index 100% rename from packages/rn-tester/android/app/src/main/res/drawable/edit_text.xml rename to packages/rn-tester/android/app/src/main/res/drawable/rn_edit_text_material.xml diff --git a/packages/rn-tester/android/app/src/main/res/values/styles.xml b/packages/rn-tester/android/app/src/main/res/values/styles.xml index e0800ee36e0c58..c0713801cb426d 100644 --- a/packages/rn-tester/android/app/src/main/res/values/styles.xml +++ b/packages/rn-tester/android/app/src/main/res/values/styles.xml @@ -3,7 +3,7 @@ diff --git a/template/android/app/src/main/res/drawable/edit_text.xml b/template/android/app/src/main/res/drawable/rn_edit_text_material.xml similarity index 100% rename from template/android/app/src/main/res/drawable/edit_text.xml rename to template/android/app/src/main/res/drawable/rn_edit_text_material.xml diff --git a/template/android/app/src/main/res/values/styles.xml b/template/android/app/src/main/res/values/styles.xml index 971d3bd148d11f..7ba83a2ad5a2c9 100644 --- a/template/android/app/src/main/res/values/styles.xml +++ b/template/android/app/src/main/res/values/styles.xml @@ -3,7 +3,7 @@ From 9a544a0f87419db702cf538ed97355bff7cb13f3 Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Wed, 15 Sep 2021 11:50:35 +0800 Subject: [PATCH 09/12] adding explanatory comments to rn_edit_text_material --- .../app/src/main/res/drawable/rn_edit_text_material.xml | 9 +++++++++ .../rn-tester/android/app/src/main/res/values/styles.xml | 2 ++ .../app/src/main/res/drawable/rn_edit_text_material.xml | 9 +++++++++ 3 files changed, 20 insertions(+) diff --git a/packages/rn-tester/android/app/src/main/res/drawable/rn_edit_text_material.xml b/packages/rn-tester/android/app/src/main/res/drawable/rn_edit_text_material.xml index 40b9f49b2667c6..f35d9962026a85 100644 --- a/packages/rn-tester/android/app/src/main/res/drawable/rn_edit_text_material.xml +++ b/packages/rn-tester/android/app/src/main/res/drawable/rn_edit_text_material.xml @@ -20,6 +20,15 @@ android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"> + diff --git a/packages/rn-tester/android/app/src/main/res/values/styles.xml b/packages/rn-tester/android/app/src/main/res/values/styles.xml index c0713801cb426d..afbf5ae047b52a 100644 --- a/packages/rn-tester/android/app/src/main/res/values/styles.xml +++ b/packages/rn-tester/android/app/src/main/res/values/styles.xml @@ -1,9 +1,11 @@ + + diff --git a/template/android/app/src/main/res/drawable/rn_edit_text_material.xml b/template/android/app/src/main/res/drawable/rn_edit_text_material.xml index 40b9f49b2667c6..f35d9962026a85 100644 --- a/template/android/app/src/main/res/drawable/rn_edit_text_material.xml +++ b/template/android/app/src/main/res/drawable/rn_edit_text_material.xml @@ -20,6 +20,15 @@ android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"> + From a6cd5898bcaa32722aa675cbecdad2e35a8ef0ab Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Wed, 15 Sep 2021 11:53:20 +0800 Subject: [PATCH 10/12] minor format change --- packages/rn-tester/android/app/src/main/res/values/styles.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/rn-tester/android/app/src/main/res/values/styles.xml b/packages/rn-tester/android/app/src/main/res/values/styles.xml index afbf5ae047b52a..42c90f3e99a984 100644 --- a/packages/rn-tester/android/app/src/main/res/values/styles.xml +++ b/packages/rn-tester/android/app/src/main/res/values/styles.xml @@ -8,4 +8,3 @@ - From 6c7b3d070ac8fc98b71f5c3d858d17b8351dd3af Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Wed, 22 Sep 2021 10:52:42 +0800 Subject: [PATCH 11/12] updating TextInputKeyProp layout --- .../rn-tester/js/examples/TextInput/TextInputKeyProp.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js b/packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js index 20650ac08a9e65..0b7ccf5fa7f2e1 100644 --- a/packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js +++ b/packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js @@ -10,9 +10,8 @@ 'use strict'; -const React = require('react'); -const {View, TextInput} = require('react-native'); -const {useEffect, useState} = React; +import React, {useEffect, useState} from 'react'; +import {View, TextInput} from 'react-native'; function TextInputKeyProp() { const [startKey, setStartKey] = useState(0); @@ -37,7 +36,7 @@ function TextInputKeyProp() { return {textInputs}; } -exports.title = ''; +exports.title = 'TextInputs with key prop'; exports.description = 'Periodically render large number of TextInputs with key prop without a Runtime Error'; exports.examples = [ From c447b25c01ce5665a7888ac0f902bdcacb87d6ed Mon Sep 17 00:00:00 2001 From: fabriziobertoglio1987 Date: Wed, 22 Sep 2021 19:14:13 +0800 Subject: [PATCH 12/12] fix failing CI test --- packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js b/packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js index 0b7ccf5fa7f2e1..a16bcb87d0e2d5 100644 --- a/packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js +++ b/packages/rn-tester/js/examples/TextInput/TextInputKeyProp.js @@ -10,8 +10,9 @@ 'use strict'; -import React, {useEffect, useState} from 'react'; -import {View, TextInput} from 'react-native'; +const React = require('react'); +const {View, TextInput} = require('react-native'); +const {useEffect, useState} = React; function TextInputKeyProp() { const [startKey, setStartKey] = useState(0);