Author: sam
Original: http://blog.isming.me/2016/08/08/red-android-evolution/
The first version of the Xiaohongshu Android client was released on August 8, 2014. Now, over two years have passed since the release of the Xiaohongshu Android version. Let’s take this opportunity to review the evolution of Xiaohongshu’s Android version. Over these two years, we have encountered many challenges and gained a lot of experience, which we would like to share with everyone.
Xiaohongshu has evolved from the initial version 1.0 to the current version 4.7 over two years, with the installation package growing from the original 5MB to the current 17MB. The product modules have also expanded from just a community module to now include both community and e-commerce modules. The app includes various functions and modules such as community, e-commerce, payment, push notifications, live streaming, and analytics. So let’s get started.
Function Evolution
Over two years and more than 30 versions, many features have undergone tremendous changes. Our new user welcome page has evolved from an initially flashy effect to a more stable and simple version. Initially, Zhong Daxia spent countless days and nights creating multiple welcome page animations. Although they are no longer in use, we have learned some new technologies. Later, Zhong Daxia contributed these to the GitHub open-source community.
Download link:https://github.com/w446108264/XhsParallaxWelcome
Download link: https://github.com/w446108264/XhsWelcomeAnim
The community is one of the core values of Xiaohongshu, and notes are the core embodiment of the Xiaohongshu community. Undoubtedly, note publishing is one of the core functions of the Xiaohongshu app. We have been optimizing our note publishing process and functions in both product and technology, including expanding from only supporting single image sharing to now supporting multiple images for simultaneous publishing. We also support richer image editing effects and a more convenient note publishing process.
The presentation format of Xiaohongshu notes is similar to that of most other image social apps, and we also support tagging on images. Initially, the tags on Xiaohongshu were similar to those of other apps, being black tags. However, after version 3.0, Xiaohongshu created a unique tree-structured tag system, providing users with a refreshing experience that has been emulated by other apps. The new tags also brought many challenges to technology, as we redefined the structure of tags and the generation and display of tags. You can check my previous blog to see how I animated the tags. (http://blog.isming.me/2016/06/07/path-property-animation/)
There are many more changes in UI redesign and functionality, which I will not mention one by one here. The overall style of Xiaohongshu Android is consistent with iOS, but we started adapting to Material Design for the details within the app at the beginning of 2015, including button styles, click effects, font specifications, dialog boxes, etc., hoping to bring a better user experience to Android users.
Technology Selection Evolution
In terms of technology selection, I will mainly talk about the upgrade of the network layer framework and the image loading library.
Network Framework Evolution
The initial framework of the app was completed by Zhong Daxia in about ten days, including the basic network request framework, the overall architecture of the app, and some main features. The principle for selecting the framework at that time was to choose what we were most familiar with, so we adopted the async-http
framework as our underlying network request framework, which fulfilled the asynchronous requests and callbacks.
However, less than half a year later, we decided to replace it with Volley. After the replacement, the underlying network request code became clearer. The results returned by Volley directly provided the objects we needed, while unified error handling, public parameter processing, and some commonly used return parameters were all placed in our custom Request, reducing the number of parameters required for external requests and simplifying error handling. We only needed to consider the Response required for the business, and other global return contents would not interfere. The introduction of Volley made our business development much more convenient. Initially, Volley used HttpClient + HttpURLConnection, but later we discovered that OkHttp, which uses NIO, is more efficient and was introduced as the system’s underlying network request, so we also replaced Volley’s underlying layer with OkHttp.
Meanwhile, Xiaohongshu’s API requests were continuously evolving towards RESTful. We encountered a problem where it was often troublesome to find the definition of an API. Around November 2015, we introduced Retrofit, which, after some modifications, supported the construction of public parameters and improved support for GsonConvert to directly return the objects we needed. The good support for RESTful style provided us with great convenience. With RxJava, we could easily make multiple API requests simultaneously and switch between multiple threads for API returns.
Image Loading Framework Evolution
Xiaohongshu notes are primarily composed of images and text, leading to a high demand for image display. Similar to the network framework selection, we initially chose UIL for image loading, which could support both local and network images, meeting our basic needs at that time.
At the beginning of 2015, we started using higher-resolution images, which slowed down loading speed and consumed more memory, and at that time, the author of UIL was hardly maintaining it. We began researching new image loading frameworks. At that time, Fresco had just come out and was not very stable, so we hesitated to use it. Our options were Picasso and Glide. Picasso is lightweight, but it didn’t significantly improve performance compared to UIL. Glide has a larger codebase, but it saves multiple caches locally (original images and images of actual display sizes), allowing for quicker local cache display and reducing decoding time, making it much faster than UIL.
In the second half of 2015, we needed to support GIF animations, and Glide’s compatibility with animations was not particularly good, so we switched directly to Fresco. At the same time, Fresco’s good support for webp greatly reduced our workload when we later switched to webp format. Fresco uses anonymous memory as memory cache for versions 4.4 and below, making a significant contribution to reducing OOM.
Each of the image loading frameworks we used has significant differences, leading to a huge workload during migration. To reduce migration costs, we encapsulated our own ImageLoader to implement specific image loading, ensuring that during migration, we minimized code changes (although the migration to Fresco still required significant changes because we could not directly use ImageView o(︶︿︶)o).
Push Notification Upgrade
I think it’s also necessary to mention push notifications. Initially, we quickly chose Baidu Cloud Push, which seemed stable and easy to integrate at that time. However, after using it for a year, we found that the delivery rate was not particularly high, and the data statistics were not well done, making it difficult to assess the effectiveness of push notifications. After research, we decided to migrate to a model using Xiaomi Push + Umeng Push, enabling Xiaomi Push for Xiaomi users while using Umeng Push for other users. To ensure a smooth transition, during the switch, we continued to use Baidu Cloud Push for users who had not upgraded.
Architecture Upgrade
Due to the time consumed by business development, the overall architecture of the app has not undergone significant changes.
In terms of the use of adapters, we placed the ListView or RecyclerView items into separate ItemHandlers so that different pages could assemble different items together to meet various needs. This allows for code reuse in ListView or RecyclerView, improving code maintainability.
As mentioned earlier regarding network layer error handling, we have made significant upgrades. Initially, network errors, HTTP request errors, and errors between the backend and client were handled at different levels. Now, when an error occurs, we throw all errors as exceptions, allowing for error handling at the upper layer.
For state synchronization in the app, we initially used database caching for some data or LocalBroadcast for broadcasting communication, but the former had many limitations, and the latter was relatively complex to use. Recently, we switched to EventBus for state synchronization, which also reduced coupling between different pages.
A significant portion of the app involves network request data, which is then displayed, primarily following the MVC pattern. In some modules, we have tested data binding, MVP, etc. In the future, we will have more opportunities for large-scale refactoring.
Other Peripheral Evolutions
Initially, we used Eclipse for development, but it lasted less than a month. After my earnest persuasion, Zhong Daxia and I switched to Android Studio. This led to our project directory still using the directory format from the Eclipse era until early this year when we finally switched to the directory format recommended by Android Studio. After switching the directory, it greatly facilitated the differentiation between debug and release.
The APK initially was about 5MB, peaking at 23MB. We have made some efforts to reduce the app size, mainly by using tinypng to compress images and retaining only arm support. The complexity of the project also made each compilation slower. You can check my previous blog on gradle acceleration http://blog.isming.me/2015/03/18/android-build-speed-up/.
Continuous integration is quite popular now, and naturally, we are using it as well. Initially, we had to manually package every day, upload the APK to the fir website, and then announce in the company WeChat group that we had released a new package. After some time, we wrote a Gradle plugin to help us automatically upload to fir. Later, we set up Jenkins to automatically complete this series of steps and notify everyone by email, allowing us to enjoy our work.
To Be Continued
This article introduces some significant changes over the past two years. It may not be possible to cover everything in one article, so I will leave it at that for now. Currently, there have not been any major changes in the project’s organizational structure, but we are conducting some small-scale tests and will continue to evolve and progress.
About Java and AndroidExpert Channel
The Java and Android Expert Channel is a public account with tens of thousands of followers discussing Java and Android development, sharing and creating the most valuable articles to help you become an expert in this field!
We discuss cutting-edge technologies in Android and Java development: Android performance optimization, pluginization, cross-platform, dynamicization, strengthening and anti-cracking, etc., and also discuss design patterns/software architecture. We are a team composed of engineers from BAT.
Follow us for a red envelope, reply with: “Baidu”, “Ali”, “Tencent” for surprises!!! You can join the WeChat group after following us. The group consists of experts from Baidu, Alibaba, and Tencent.
Welcome to follow us, let’s discuss technology together. Scan and long-press the QR code below for quick access. Or search for the public account: JANiubility.
Public account:JANiubility
Leave a Comment
Your email address will not be published. Required fields are marked *