We restricted our keys when our app was two years old. Afterwards, one of our maps didn’t work. We rolled the change back, and it took a while to figure out why. It turns out that the official Google package that we used in most places in the app handled the change with no problem. But we had to write custom code for one map didn’t account for the possibility of restricted keys, which require a different API call. If we had restricted the API keys from day one, it might have added time to development, but the story would have ended there.
But it didn’t end there. In order to restrict the API keys and not break that one map, we had to force an update. We had stats we could watch as users went through the update process. But it took weeks for the 90% of users who could get an update notice to get the version with the fixed map. There was still 10% of users that had to have a majorly broken version of the app and used it, but I am not sure how.
When I was primarily a web developer, I was never quite sure why someone would want to do this. After I updated the frontend code, why would I need an old version of the API around? It seemed like overkill.
But when users may have different versions of the app, a major change to your APIs can break the app for a large portion of them. In-app update will help mitigate this issue, but this process is never as quick as you think. Versioning APIs now seems more like a very simple way to prevent broken apps than the over-engineering I once thought it was.
Our app is meant to be used in the field. When we got reviews about it being unresponsive and timing out, I was so clueless about mobile development that I discovered a new term, offline first. If our users didn’t have a connection, anything they tried to save was lost and they would have to re-enter everything once they re-connected.
Offline first architecture will write changes to a local database before syncing that with the web connection. This not only allows users with no connection to use your app but also makes the app more responsive when it does have a connection, because it doesn’t have to wait for a response from a remote server to go to the next task.
This can be harder to implement later than in the beginning, depending on the complexity of your data. So decide if your app needs it now. We are still working out how we will do this.
If your Android app is complex with a lot of views, changing navigation late in development may be harder than it would seem. We switched to bottom navigation late in our app’s life.
For some background, activities in Android can thought of as the code for a screen in your app. Fragments were added later to Android and you can think of them as the code for sub-views or partials in the app. Both of these will have a layout defined in XML.
We started with navigation that consisted of a dashboard of cards that linked to the main activities in each section of the app. These then branched out to more activities for a total of over 30 activities. There were only about four fragments in our app. They were used in places we used tab views. Our app was designed based on activities. Drawer navigation is another common type of navigation that is designed for activity to activity navigation.
Bottom navigation is designed for fragment navigation because the bottom bar is always visible. If the bottom bar is added to an activity, you only have to add the code for it to that activity, and its view to that activity’s layout. Then load a fragment in the activity when a button on the bar is clicked.
So to add a bottom navigation bar to our app, I tried converting the activities to fragments. It took a month, it was full of bugs that actually caused the app to crash, and it was a waste of time. With 5 or 6 activities, I may have tried to fix the bugs, but not with 30.
So we threw that work away and I spent a month adding functionality for the navigation to every activity. I did create a helper class but there was still code that had to be added to each activity. The bar also had to be added to each layout, and space had to be made for it. I also had to manually manipulate the activity stack to prevent race conditions. It was not fun, but it the end it works pretty well. It just would have been easier to start with it and a fragment-based design.
Of course, there are all the common things you should do before beginning your first Android application, like adding unit tests and picking some sort of pattern for your app and sticking to it, but if you have been exposed to any other type of development, you should just know these type of things. You may not run into issues exactly like mine, but I know you will run into a few that are similar. Hopefully, these tips help you remember Android development is slightly different and some development decisions you make will stick around for longer than you think.