[Android] Avoiding API Calls in the Application Class
This is the Day-2 post of the KINTO Technologies Advent Calendar 2024 🎅🎄
Introduction
Hello! I am Hasegawa, an Android engineer at KTC!
This article highlights common mistakes developers often make when working with the Application class in Android development and offers solutions to prevent them.
What is the Application Class?
The Application class in Android can be described using the official documentation as follows:
"Base class for maintaining global application state. It is instantiated before any other class for your application/package is created."
This means that it is responsible for maintaining a global state and is instantiated before any other class in the application.
While implementation may vary depending on the project, the Application class is generally used for tasks such as initializing libraries used throughout the app or configuring Dependency Injection (DI).
class MyApplication: Application() {
override fun onCreate() {
super.onCreate()
// Library initialization
// DI setup
}
}
What would happen if you made an API call to fetch data from the server during the application startup?
class MyApplication: Application() {
override fun onCreate() {
super.onCreate()
// Library initialization
// DI setup
// API call
}
}
At least in my experience, I’ve come across code like this more than once. Although it may not cause immediate issues, it could lead to problems down the line. In this article, I’ll discuss scenarios where this code might lead to issues.
The Connection Between the Four Android App Components and the Application Class
To understand why making API calls in the Application class can be problematic, it’s essential to have a good grasp of Android’s 4 app components. The diagram below shows these four components and the typical features associated with each.
Activities are primarily responsible for managing the app's user interface and navigation between screens, making them the most commonly used component. Apps that provide notification functionality often rely on Services. Apps with widget functionality typically use Broadcast Receivers. Content Providers may be less commonly used, but they are useful for sharing your app’s data with other apps.
It's important to note that the Application class is instantiated whenever any of these components are active.
Notably, components other than Activities can run even if the user hasn't explicitly opened the app.
For instance, in apps with widgets, the Application class may be instantiated when the device restarts, triggering the widget to be recreated. At this point, if the Application class includes API calls, they might be triggered even when the user hasn’t opened the app, potentially occurring at times unintended by the developer.
In apps with notification functionality, the Application class might be instantiated when a push notification is received If push notifications are sent to multiple users simultaneously, API calls could be triggered at the same time, potentially causing a situation similar to a DDoS attack.
This issue might only surface later, such as when the user base expands. Hence, it’s crucial to recognize this risk and include it in your knowledge base.
What If You Want to Make an API Call at Startup?
There are many possible solutions, so there is no single “correct” answer. However, here’s one example:
Data should be fetched only when and where it is necessary, and in the precise amount needed. Hence, it’s best to retrieve data within the context of each of the four components. If the fetched data needs to be reused across components, you can persist it locally, store it in the Application class, or use dependency injection (DI) to store it in a class with a Singleton lifecycle scope.
Conclusion
Thank you for taking the time to read this article.
Today we explored the Application class lifecycle, highlighting key implementation considerations to keep in mind. Specifically, I examined the use of API calls in the Application class as an example. Another frequent issue developers encounter is sending events —such as app startup events—, directly from the Application class. As mentioned earlier, the instantiation of the Application class does not always align with the moment a user explicitly launches the app. If the event is triggered by the user launching the app, it should be managed within the Activity. Even in apps with multiple activities, it's crucial to identify the correct entry point for the app.
I hope this article proves helpful to your development journey.
*The Android robot is reproduced or modified from work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.
関連記事 | Related Posts
The story of how I struggled with the character code when I got OGP in Kotlin
Android Compose Object-Oriented Navigation
Potential Bug Triggers in Android Development Due to Regional Preferences
Jetpack Compose in myroute Android App
Introducing the Woven Payment Solution Development Group
Android Development: How to Effectively Trigger Impression Events With Multiple RecyclerViews
We are hiring!
【プロジェクトマネージャー】モバイルアプリ開発G/大阪
モバイルアプリ開発GについてKINTOテクノロジーズにおける、モバイルアプリ開発のスペシャリストが集まっているグループです。KINTOやmy routeなどのサービスを開発・運用しているグループと協調しながら品質の高いモバイルアプリを開発し、サービスの発展に貢献する事を目標としています。
【iOSエンジニア】モバイルアプリ開発G/大阪
モバイルアプリ開発GについてKINTOテクノロジーズにおける、モバイルアプリ開発のスペシャリストが集まっているグループです。KINTOやmy routeなどのサービスを開発・運用しているグループと協調しながら品質の高いモバイルアプリを開発し、サービスの発展に貢献する事を目標としています。