Application Architecture Decision Records
- Summary: In order to program functionality into our app easily, we decided to use the official android app development language, Kotlin.
- Problem: In developing for Android, you can use Java or Kotlin, so being on the same page is very important. We want our code to easily operate with itself and android libraries.
- Constraints: There are only a couple of languages that can be run on JVM based Android phones and we have to choose from them. We will have to be able to work with Android libraries as well, since we have to access phone battery information.
- Options: We have two primary options, Java and Kotlin. Java is well known amongst team members, but Kotlin is easy to learn as it reads like a simplified Java. Kotlin is the official Android development language and it is faster to develop with than Java.
- Rationale: Since Kotlin has the most advantages and is worth learning for two of our team members who are new to the language, we decided that the team and project would benefit most from using Kotlin to develop with.
- Summary: In order to persist monitored energy usage locally between app sessions, we decided to use the Room Persistance Library.
- Problem: Our app will be monitoring the phone's energy usage constantly in the background, regardless of whether a connection to the backend server is available. Often, the app will be killed without notice. We need a way to store data between app sessions so that we don't lose data before syncing it with the backend server
- Constraints: We cannot store the data solely in the cloud or off-device, because we need to be able to record data when an internet connection is not available. We also cannot store data in volatile memory, because we need data to be available across app sessions. We are asussming that the client wants as much recorded data as possible, and that loss of data should be avoided.
- Options: We are considering using the Room Persistance Library, App Specific Storage, and Preferences. App specific storage offers the most flexibility because we can store arbitrary files, but introduces unnecessary complexity for our implementation. Preferences would be easiest to use because they are simply Key-Value pairs, but they are not well suited for streaming temporal data. Room requires that data be relationally structured.
- Rationale: We went with the Room Persistance Library because it operates at the appropriate abstraction for our problem. Our streaming temporal data is relational by nature, and is well suited for the SQL-like database that Room offers.
- Summary: We decided not to use a framework since our app is only possible on one platform, Android.
- Problem: We needed to decide how we were going to develop our app as the architecture is heavily dependent on the framework used. If we develop for more than one platform, it can be a major time saver to use a framework.
- Constraints: The constraints of the iOS platform will not allow developers to access battery information, which means that our app cannot be functional on iOS. Thus we only need to develop for Android. Our decision is therefore to develop natively versus in a framework, but only for one platform. We also need to be able to access native functionality on Android, the battery data, which is often not accessible from a framework.
- Options: Based on the constraints we have two viable options, developing natively for Android in Kotlin, or doing Kotlin multiplatform. Both can access native libraries although Kotlin has a slightly larger amount of overhead. This increase in overhead will allow for our app to deploy to multiple platforms, but since our app cannot work on iOS, there is no value gained from the additional overhead. Additionally, we can always implement new features in Kotlin multiplatform later on if the battery information becomes available to developers on iOS.
- Rationale: We chose to develop natively in Kotlin on Android since it has the least overhead and most community support available.
- Summary: We decided to use the existing backend service that our client has in place in order to manage accounts, sync recorded data, and pull previous data.
- Problem: We need a backend service to store our recorded energy data off-device. This allows users to access their data from multiple devices, and allows our client to see their users' energy consumption data. Our backend service would need to accept frequent updates from many users, and would need to serve updated data with low latency to users in order to facilitate a good UX within the app.
- Constraints: We are constrained to using a backend service that aligns well with the infrastructure our client currently has in place. If we heavily modify the backend service, our client would need to redesign their current architecture - something we need to avoid. We also need to accommodate the current user model so that existing users can seamlessly transition to using our app.
- Options: Some options that we have are using a paid cloud provider like AWS, Azure, or Google Cloud, using a free lightweight provider like Heroku, and using our clients existing backend service. Using a paid provider to create our own backend service would offer the greatest flexibility and performance, but it would cost money, time, and potentially conflict with the client's existing service. A free provider would be cost-effective, but may suffer in performance if many users adopt the app. The client's existing service offers a seamless transition, but may suffer with performance and limits flexibility.
- Rationale: We chose to use our client's existing backend service because it solves our current problems without conflicting with the infrastructure that they have in place. If performance becomes an issue in the future, our client can add resources to their backend service and continue to interface with our app without too much difficulty.
- Summary: In order to develop an aesthetically consistent and user friendly frontend, we will be creating a frontend based on our Figma diagrams with existing Embit logos and using the MPAndroidChart library for displaying our dynamic data.
- Problem: We need to create a straightforward frontend that will be self explicative and informative to users.
- Constraints: We are constrained by preexisting logos and branding for Embit, which we have already implemented in our Figma diagrams. We are also constrained to an existing graphing library for Android.
- Options: We have only one option for the frontend resources and branding. For graphing, we have two choices, MPAndroidChart and GraphView. Both appear to be great options for graphing, but MPAndroidChart has more tutorials immediately available and is a more popular library.
- Rationale: We have decided to use MPAndroidChart since it has the capability to create the graphs that we have in mind and it has larger community support, which will make learning and working with the library a smoother experience.