Skip to content

Commit 254493e

Browse files
fabOnReactfacebook-github-bot
authored andcommitted
Fix - TextInput Drawable to avoid Null Pointer Exception RuntimeError #17530 (#29452)
Summary: This issue fixes #17530 fixes expo/expo#9905 with the help of sunnylqm https://github.com/sunnylqm Re-rendering a large number of TextInputs with key prop on the screen will trigger the below 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 error is caused by null.newDrawable(mSourceRes) at https://github.com/aosp-mirror/platform_frameworks_base/blob/20b012282e0c3d94b5c0aa799cdda065f2df06db/graphics/java/android/graphics/drawable/DrawableContainer.java#L919 More info #29452 (comment) #17530 (comment) The Theme Theme.AppCompat.Light.NoActionBar defines the Drawables for AppCompatEditText 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 Removing the following line from the above xml file drawable/abc_edit_text_material.xml fixes the error #17530 (comment) `<item android:state_pressed="false" android:state_focused="false" android:drawable="drawable/abc_textfield_default_mtrl_alpha"/>` The Theme default EditText background is replaced with a custom background, which is a copy of the original background without the above item which triggers the Runtime Error. The changes are implemented in RNTester with commit (more info in the commit) 0858d41. The new custom drawable used as default background for the TextInput is named edit_text. `<item name="android:editTextBackground">drawable/edit_text</item>` The same changes have been added to react-native default template for creating new applications with commit (more info) f349308, lean core moved the cli tools to https://github.com/react-native-community/cli, but the default template for creating a new application is stored in facebook/react-native/template. New applications will be generated with this configurations and will not experience the error, existing react-native applications will fix the error by upgrading with the [upgrade-helper](https://github.com/react-native-community/upgrade-helper). A Minimum Reproducible Example to reproduce this error is included in commit (more info in the commit) fabOnReact@4a414e2 and #17530 (comment) ## Changelog <!-- Help reviewers and the release process by writing your own changelog entry. For an example, see: https://github.com/facebook/react-native/wiki/Changelog --> [Android] [Fixed] - TextInput Drawable to avoid Null Pointer Exception RuntimeError #17530 Pull Request resolved: #29452 Test Plan: Works in all scenarios on Android. **<details><summary>CLICK TO OPEN TESTS RESULTS - React Native</summary>** <p> Test Results from the Testing in RNTester. Minimum Reproducible Example added with commit (more info in the commit) fabOnReact@4a414e2 The example included in commit fabOnReact@4a414e2 will cause a [NPE Runtime Error on Master Branch](https://fabriziobertoglio.s3.eu-central-1.amazonaws.com/opensource/react-native/17530/runtime.mp4), while no error is experienced in the [feature branch](https://fabriziobertoglio.s3.eu-central-1.amazonaws.com/opensource/react-native/17530/no_runtime.mp4). The links are video hosted on s3 of this tests (playable by google chrome). | **[BEFORE](https://fabriziobertoglio.s3.eu-central-1.amazonaws.com/opensource/react-native/17530/runtime.mp4)** | **[AFTER](https://fabriziobertoglio.s3.eu-central-1.amazonaws.com/opensource/react-native/17530/no_runtime.mp4)** | |:-------------------------:|:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/88069187-6edde400-cb71-11ea-81f2-1846144cc6c1.png" width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/88069503-d5630200-cb71-11ea-9b87-c5c49845c96d.png" width="300" height="" /> | The below screenshots were taken to detect any issues with the EditText Background. There is no difference between master and feature branch. | **BEFORE** | **AFTER** | |:-------------------------:|:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/88071948-c0d43900-cb74-11ea-9a86-522b13e79f04.png" width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/88074345-90da6500-cb77-11ea-8ced-8b34a3c5a299.png" width="300" height="" /> | | **BEFORE** | **AFTER** | |:-------------------------:|:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/88071966-c598ed00-cb74-11ea-8db8-c07dce3a99b6.png" width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/88074654-fcbccd80-cb77-11ea-961c-f39a60a1aa62.png" width="300" height="" /> | | **BEFORE** | **AFTER** | |:-------------------------:|:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/88071989-cc276480-cb74-11ea-9eab-9ad4f858d0fb.png" width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/88074673-00505480-cb78-11ea-8ff5-ea5fc9ef1b8e.png" width="300" height="" /> | | **BEFORE** | **AFTER** | |:-------------------------:|:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/88072003-d0ec1880-cb74-11ea-9285-792b2dc08187.png" width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/88074685-03e3db80-cb78-11ea-86a5-da2700826eea.png" width="300" height="" /> | | **BEFORE** | **AFTER** | |:-------------------------:|:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/88072080-e7926f80-cb74-11ea-9f08-bb26eabbd5a0.png" width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/88074866-4a393a80-cb78-11ea-9b37-80c019909d7d.png" width="300" height="" /> | | **BEFORE** | **AFTER** | |:-------------------------:|:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/88072100-ed885080-cb74-11ea-8450-bafa2b7a9989.png" width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/88074976-7359cb00-cb78-11ea-8bf3-d50566cbb3ba.png" width="300" height="" /> | | **BEFORE** | **AFTER** | |:-------------------------:|:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/88072113-f1b46e00-cb74-11ea-9143-7e74872f2670.png" width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/88074880-502f1b80-cb78-11ea-8bfc-f67efec283d3.png" width="300" height="" /> | | **BEFORE** | **AFTER** | |:-------------------------:|:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/88072118-f547f500-cb74-11ea-8ba3-8a245fdf0bc3.png" width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/88074883-52917580-cb78-11ea-9230-71aeb5c35582.png" width="300" height="" /> | | **BEFORE** | **AFTER** | |:-------------------------:|:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/88072139-fb3dd600-cb74-11ea-9212-485f788648f1.png" width="300" height="" />| <img src="https://user-images.githubusercontent.com/24992535/88075031-85d40480-cb78-11ea-8068-50f04ebbff54.png" width="300" height="" /> | | **AFTER** | |:-------------------------:| | <img src="https://user-images.githubusercontent.com/24992535/88071330-f75d8400-cb73-11ea-800d-359336c8d51e.png" width="300" height="" />| </p> </details> **<details><summary>CLICK TO OPEN TESTS RESULTS - React Native Cli</summary>** <p> As lean core move cli tools to https://github.com/react-native-community/cli, I tested the changes to the template in a separate repository https://github.com/fabriziobertoglio1987/react-native-template and generated the template with the following command ``` npx react-native init ProjectName --template file:///home/fabrizio/Documents/sourcecode/opensource/react-native-template/template ``` The generated app did not experience any issues and includes all the changes in [rn_edit_text_material.xml](https://github.com/fabriziobertoglio1987/react-native-template/blob/master/ProjectName/android/app/src/main/res/drawable/rn_edit_text_material.xml) and [styles.xml](https://github.com/fabriziobertoglio1987/react-native-template/blob/master/ProjectName/android/app/src/main/res/values/styles.xml) </p> </details> Reviewed By: cortinico Differential Revision: D30684030 Pulled By: lunaleaps fbshipit-source-id: 7404da0a7259a4bc0405e57e5ed908649d180524
1 parent fabd253 commit 254493e

File tree

7 files changed

+131
-1
lines changed

7 files changed

+131
-1
lines changed

packages/rn-tester/android/app/src/main/AndroidManifest.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
android:banner="@drawable/tv_banner"
3131
android:icon="@drawable/launcher_icon"
3232
android:label="@string/app_name"
33-
android:theme="@style/Theme.ReactNative.AppCompat.Light" >
33+
android:theme="@style/AppTheme">
3434
<activity
3535
android:name=".RNTesterActivity"
3636
android:label="@string/app_name"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- Copyright (C) 2014 The Android Open Source Project
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
<inset xmlns:android="http://schemas.android.com/apk/res/android"
17+
android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
18+
android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
19+
android:insetTop="@dimen/abc_edit_text_inset_top_material"
20+
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material">
21+
22+
<selector>
23+
<!--
24+
This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).
25+
The item below with state_pressed="false" and state_focused="false" causes a NullPointerException.
26+
NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)'
27+
28+
<item android:state_pressed="false" android:state_focused="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
29+
30+
For more info, see https://bit.ly/3CdLStv (react-native/pull/29452) and https://bit.ly/3nxOMoR.
31+
-->
32+
<item android:state_enabled="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
33+
<item android:drawable="@drawable/abc_textfield_activated_mtrl_alpha"/>
34+
</selector>
35+
36+
</inset>

packages/rn-tester/android/app/src/main/res/values/styles.xml

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
55
<!-- Customize your theme here. -->
66
<item name="android:textColor">#000000</item>
7+
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
78
</style>
89

910
</resources>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @format
8+
* @flow
9+
*/
10+
11+
'use strict';
12+
13+
const React = require('react');
14+
const {View, TextInput} = require('react-native');
15+
const {useEffect, useState} = React;
16+
17+
function TextInputKeyProp() {
18+
const [startKey, setStartKey] = useState(0);
19+
20+
useEffect(() => {
21+
const interval = setInterval(() => setStartKey(startKey + 100), 3000);
22+
return () => clearInterval(interval);
23+
}, [startKey]);
24+
25+
const textInputs = [];
26+
for (let i = 0; i < 101; i++) {
27+
const key = (startKey + i).toString();
28+
console.log('Adding a TextInput with key ' + key);
29+
textInputs.push(
30+
<TextInput
31+
style={{height: 40, borderColor: 'gray', borderWidth: 1}}
32+
key={key}
33+
/>,
34+
);
35+
}
36+
37+
return <View>{textInputs}</View>;
38+
}
39+
40+
exports.title = 'TextInputs with key prop';
41+
exports.description =
42+
'Periodically render large number of TextInputs with key prop without a Runtime Error';
43+
exports.examples = [
44+
{
45+
title: 'Long List of TextInputs with key props',
46+
description:
47+
'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 <TextInput> example.',
48+
render: function(): React.Node {
49+
return <TextInputKeyProp />;
50+
},
51+
},
52+
];

packages/rn-tester/js/utils/RNTesterList.android.js

+4
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ const Components: Array<RNTesterModuleInfo> = [
105105
category: 'Basic',
106106
module: require('../examples/TextInput/TextInputExample'),
107107
},
108+
{
109+
key: 'TextInputs with key prop',
110+
module: require('../examples/TextInput/TextInputKeyProp'),
111+
},
108112
{
109113
key: 'TouchableExample',
110114
category: 'UI',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- Copyright (C) 2014 The Android Open Source Project
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
<inset xmlns:android="http://schemas.android.com/apk/res/android"
17+
android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material"
18+
android:insetRight="@dimen/abc_edit_text_inset_horizontal_material"
19+
android:insetTop="@dimen/abc_edit_text_inset_top_material"
20+
android:insetBottom="@dimen/abc_edit_text_inset_bottom_material">
21+
22+
<selector>
23+
<!--
24+
This file is a copy of abc_edit_text_material (https://bit.ly/3k8fX7I).
25+
The item below with state_pressed="false" and state_focused="false" causes a NullPointerException.
26+
NullPointerException:tempt to invoke virtual method 'android.graphics.drawable.Drawable android.graphics.drawable.Drawable$ConstantState.newDrawable(android.content.res.Resources)'
27+
28+
<item android:state_pressed="false" android:state_focused="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
29+
30+
For more info, see https://bit.ly/3CdLStv (react-native/pull/29452) and https://bit.ly/3nxOMoR.
31+
-->
32+
<item android:state_enabled="false" android:drawable="@drawable/abc_textfield_default_mtrl_alpha"/>
33+
<item android:drawable="@drawable/abc_textfield_activated_mtrl_alpha"/>
34+
</selector>
35+
36+
</inset>

template/android/app/src/main/res/values/styles.xml

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
<!-- Base application theme. -->
44
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
55
<!-- Customize your theme here. -->
6+
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
67
</style>
78

89
</resources>

0 commit comments

Comments
 (0)