In a previous blog post, Allen explained how React Native works with Glow and how it works. Due to some reasons, the Maturity of React Native library on Android is far less than that of iOS, which brings more challenges to Android applications.
In this article, I will share some of the problems and solutions encountered in the process of integrating React Native on the Android platform.
64 – bit support
Runtime runtime: React Native Runtime: Runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: runtime: scenario So if your application already contains 64-bit binaries, you must use abiFilters to remove the 64-bit binaries.
ndk {
abiFilters "armeabi", "mips", "armeabi-v7a", "x86"
}
Copy the code
React Native is also working to address this issue (React Native for Android is incompatible with 3rd-party 64-bit libraries), The only dependency that seems to remain is Android-JSC, and the PR is already in place.
APK size
Another problem with React Native is the size of APK files. 32-bit support alone increases apK size by approximately 8MB. If this is sensitive, we can consider using multiple APK techniques to solve this problem, but we didn’t use them because of the complexity of versioning.
Since x86 models are scarce in the market, we tried to drop support for x86, which saved about 4MB of space. It didn’t work out well because the Play Store didn’t seem to recognize x86 devices 100% correctly, making them unusable when downloaded on some devices. Maybe it had something to do with the fact that we dropped x86 support in the middle of the application, but couldn’t verify it and had to abandon it.
In addition, it is recommended to read Google’s Reduce APK Size proposal carefully to Reduce the Size of APK.
JS stack record
For error trapping within JS, we use a Sentry + Raven-JS solution. However, it was found that the JS stack record could not be correctly captured on Android because raven-JS cannot correctly parse Android StackTrace. The final solution is to patch Raven-JS in the packaging script.
Another problem found is that the stack records on Android are offset in some cases and only appear on minify’s JS code. This problem has not been solved yet, but fortunately in most cases the correct error code can be found based on the information in the exception itself. If there are readers who understand this problem, please do not hesitate to comment.
ListView performance problem
In React Native 0.42.3, we found a serious problem with the ListView on Android: The ListView would stop responding for more than a second after scrolling, and could not respond to any click events during this period.
After spending a lot of time debugging, it was found that a function calculating layout in React Native occupied quite a lot of CPU time during ListView scrolling. Finally, it was found that this was also a bug introduced by React Native after 0.40.0. React Native made too many unnecessary layout calculations. See Extreme lag after upgrade to 0.39.2 and 0.40.0 for details.
By upgrading React Native to 0.44.0, the problem was resolved, but the related fix also caused another bug, which will be covered in the ViewPagerAndroid section later.
Images and memory
The first version after React Native integration had a lot of crashes, a large part of which was due to insufficient memory. Using Android Studio’s built-in memory analysis tool, you can see that in some scenarios some images take up too much memory (up to 20 MB in some cases). Further analysis determined the cause: the image had not been resized. Our app allows users to upload their own images, and once some images are large (note not the file size, but the length and width of the image), they take up a lot of memory when decoded.
The solution is twofold:
- Resized images are returned on the server side, reducing network overhead.
- mandatory
Image
You must specifyresizeMethod
, for images (such as ICONS) that are similar in size to the display sizescale
, must be used for images that may exceed the display size by a large marginresize
To reduce memory overhead (see the React Native documentation for details).
In order to prevent the omission of resizeMethod in the future development process, we define the following two components to replace the original Image component.
export function ResizeImage({... props}: Object): ReactNative.ReactElement { return <ReactNative.Image resizeMethod={'resize'} {... props} />; } export function ScaleImage({... props}: Object): ReactNative.ReactElement { return <ReactNative.Image resizeMethod={'scale'} {... props} />; }Copy the code
Reducing application Crash
In the crash mentioned just now, the other part was caused by React Native itself, and can be partially reproduced by using Monkey Test. ShadowNodeRegistry can be accessed by multiple threads, but it is not protected. Simply adding the synchronized keyword can fix a large percentage of crashes.
See Make ShadowNodeRegistry Thread Safe for details.
Through these two fixes, the crash free rate of each application is still well maintained
ViewPagerAndroid
Another problem discovered during development is that when pages are dynamically added to ViewPagerAndroid, the new pages do not display. After debugging, it was found that the problem was related to the Performance fix of the ListView. The performance optimization was too hard, which caused the Layout calculation of ViewPagerAndroid to be omitted.
Detailed instructions and sample code can be found in React Native V0.43 ViewPagerAndroid Work not well when detached then Attach.
For this reason, our solution is to bypass layout optimization of ViewPagerAndroid. The code can be referred to Fix ReactViewPager Layouting.
conclusion
- React Native does have more issues on Android than it does on iOS
- When you encounter a problem, you can first search the official issue list to see if there is a known problem, which can save a lot of time
- It is recommended to fork out the React Native Android library to a private repository and fix some simple problems yourself if necessary
- React Native code should be developed on both Android and iOS to avoid rework due to incompatibilities
Finally, if you have any questions, please leave a message and write to us.