07 July 2020
This blogpost is a collaboration between Google and Excelliance Tech. Authored by Zhuo Chen with support from Zhihai Wang, Gao Huang from Excelliance Tech.
Excelliance Tech improved the stability and compatibility of their LeBian SDK by moving away from non-SDK APIs, toward stable, official APIs. Their collaboration with the Android team during the process also led to a new public API for resource loading that all developers can use - the ResourcesLoader API in Android 11.
Games are becoming increasingly complex, and a loading progress bar is not only a countdown to a new adventure, but also a bridge which connects players and developers.
Players want the game to load right away, so "loading" has its own priorities: resources that will be used in the first few minutes need to be packed into the APK, while the rest of the content can be downloaded in the background after the game starts.
Developers are always creating new content for their games, so "change" is the only constant: different campaigns bring different launch screens and themes, keeping the game experience fresh for players.
Excelliance Tech’s LeBian (乐变) game assets streaming service helps game developers meet players’ needs by loading fresh resources dynamically while the game is loading or being played.
Meteor, Butterfly And a Sword (流星群侠传) by NetEase Games, Duoduo Auto Chess (多多自走棋) by Dragonest Game, Langrisser (梦幻模拟战) by ZlongGames, Junior Three Kingdom 2 (少年三国志 2) by Yoozoo Games - these games are created by different developers and have different look and feel, but one thing they have in common: they all use LeBian game streaming service to load resources.
The resource loading technology is so useful that Excelliance Tech is even using it in the LeBian SDK itself, bringing a better experience for developers. Dynamic resource loading makes the SDK much easier to use. By dynamically updating its internal resources when needed, the library doesn’t require developers to update the SDK for new resources.
Before Android 11 introduced the ResourcesLoader API, Excelliance Tech had to build their dynamic resource loading capability the hard way, using non-SDK interfaces.
When Excelliance was first building their product, Android did not offer public APIs for the dynamic resource loading use-case. The team did what they could, but ended up using non-SDK interfaces to add the external resources. While this met the technical need initially, the implementation was fragile - it depended on non-SDK interfaces, which don’t have the same compatibility guarantees as official SDK APIs and can change without notice.
As a result, Excelliance found that compatibility issues would surface unexpectedly as new versions of Android were released. These required additional testing and development to assure the stability of the product. Over many iterations, it took the Excelliance team six engineer-months and a lot of code to stabilize their solution, while knowing that it might break again in the next Android release. With Android tightening restrictions on non-SDK interfaces to achieve better stability and app compatibility, relying on those non-SDK interfaces became no longer an option.
As the Android team increased its focus on moving apps to public APIs, Excelliance saw an opportunity to migrate to a stronger foundation. They reached out to the Android team to give their feedback and highlighted their use case and need for public SDK APIs.
Over time, their collaboration led to the development of the ResourcesLoader public API that’s available for the first time in Android 11. Excelliance Tech has already moved to the new ResourcesLoader API and they’ve seen better productivity and product quality as a result. Excelliance believes the ResourcesLoader API provides advantages including the following:
String sdkroot = getApplicationInfo().dataDir + "/lebian"; ResourcesLoader rl = new ResourcesLoader(); rl.addProvider(ResourcesProvider.loadFromDirectory(sdkroot, null)); Resources res = getResources(); res.addLoaders(rl); final AssetManager assetManager = res.getAssets();
After moving to the new ResourcesLoader API, the essential code has just a few lines (down from hundreds of lines of code across a number of source files).
Excelliance Tech did a comparison test, loading 16,028 files (uncompressed 1.47GB, compressed 1.36GB) in 4 ways:
Resources are compressed in option 1, 2 and 3, and the average loading times are around 19 seconds. Option 4 loads uncompressed resources directly from a directory using ResourcesLoader, the average loading time is about 3 seconds - a 6x performance improvement!
Summarizing the overall impact of ResourcesLoader, Huang Gao, CEO & Product Lead at Excelliance Tech, said “The new ResourcesLoader API dramatically reduces development and maintenance costs and allows us to focus more on product and business innovation."
The Excelliance Tech team.
"On the Android platform, we've created some valuable products and services, which makes us want to invest more to create innovative products", Excelliance Tech stated, "We hope to have more opportunities to participate in the building of the Android ecosystem and contribute our efforts to make a better Android both for consumers and developers."
Excelliance Tech made an investment for the long-term compatibility of the LeBian SDK. Moving to the ResourcesLoader API has already yielded stability and performance benefits, reduced the complexity of their code, and reduced risks of future compatibility issues as Android rolls out new versions of the platform. The ResourcesLoader API is part of Android 11’s public APIs, benefitting the entire Android developer community.