Evolution of Android Architecture Patterns [ MV * (C, P, VM, I) | JetPack] — U Want To Learn
Wow, what a fantastic journey. Hats off to the Android community. I feel blessed I started my professional carrier with Android. I learn a lot of things from Android but that I will discuss in some other blog. For now, we will explain the evolution of Android App Architecture Patterns.
Motivation:
When I started my journey around six years ago with Android Froyo at that time, I remember we used to write everything in one file mostly Activity class :). Instead, I discuss it with my colleagues. They are primarily a big fan of one file, and I always want to make different files like Activity should not contain everything. Over time, apps are going complex, and we need to write a lot of code. As community teams start facing problems and we start searching on google how to tackle these issues. Once these questions raised, different community members begin giving their solutions to address these problems, and in the end, we find out great solutions for these issues. Now, today we have some common Android Architecture Patterns like MVP, MVVM, MVI and then different companies or group of developers gave there own customize solutions by using these generic architecture patterns. Sometimes I asked the question to myself or to community members why we need this evolution or why this evolution happened? Different fellows gave different answers sometimes they don’t know the core reason, but they enjoy the writing code in some proper manner:). Maybe I don’t understand the core reason but I will try to share my thoughts and will explain all these patterns in different parts of this series.
Note: These patterns are not new in our field. We can say the Android community took from other technologies and twisted according to Android.
Plan:
I am sure this will be a long series. In which I have a plan to explain different android architecture patterns. Other then code I will share with you many things like:
- What will be the impact of your pattern choice?
- What will be the impact of your pattern choice on business?
- How a country or city can impact on your pattern choice?
- Companies headcount and pay packages may impact on your choice?
- Always asked a question when you left the company what will happen with your pattern choice and business?
- What will be the scalability of your pattern choice?
There are many other questions which are useful to ask yourself before choosing these patterns, but I will stick with the above questions.
Most probably I will follow the below-mentioned plan:
- Evolution of Android Architecture Pattern [ MVC ]
- Evolution of Android Architecture Pattern [ MVP ]
- Evolution of Android Architecture Pattern [ MVVM ]
- Evolution of Android Architecture Pattern [ MVI ]
- Step by step MVI Android Design Pattern Slides
- Evolution of Android Architecture Pattern [Android JetPack]
All the above title may contain more than one posts.
Why did this evolution happen?
For this question, I have a feeling there are a lot of factors, but I will discuss here which I feel are essential.
- Android Framework Component Life Cycle
- Writing and Reading Code
- Testing Code
- Focused Learning Curve
Android Framework Component Life Cycle:
I feel this is the biggest reason due to which we evolved a lot our Android Architecture Patterns, and today we have some fantastic libs which are helping us to forget about the life cycle.
[ Personal Experience Sharing: On this point, I learned one thing from Android.
If you are a guru of some language or concepts and some other environment uses these then maybe you will be the person who can create more problems then solutions in the new environment by trying to applying old concepts into a new context. ]
As we know, Android uses Java as a language. In the early days of Android mostly Server side java developers start working in Android, and as my personal experience, we don’t care about the lifecycles on Server side. We love Singletons because they are easy to access from thousands of miles. As we started Android and we already have a lot of experience in Java already. So we start writing code without knowing a lot of core Android specific things and later a lot of apps start facing performance issues, Out of memory issues, Memory leaks because we used the same Server side thinking. Create a Singleton and enjoy coding. Instead, sometimes Singletons have the reference of activities, so they never garbage collected when they destroy by the OS. Many more.
Maybe due to this developers start thinking Singleton is an AntiPattern because we abuse the usage of Singleton in Android.
Same we used Network Broadcast Receiver in a horrible way, and Google bans that receiver in Marshmallow :).
Same as developers we abused the power of background Services, and Google again bans that in Oreo.
Then as an imperative coding style developer. My brain always wants everything should be sequential, but Android life cycle creates a new problem. I need to remember a lot of life cycle events then OS can do your activity close.
Second, If we are going to use thread or async tasks, we are again in a difficult situation. Maybe once we started our work in background user did some action and our app no more in the foreground. So once we got the result from the backend, we can crash our app easily. So there are many reasons which give us a tough time, and as a community, we start thinking about how to resolve these issues in a good way. After some time people start properly managing these lifecycle issues but then we start facing one more problem like I downloaded data and due to some reason activity recreated now we are going to download that data again. So these are all the factors which place a significant role to create amazing architectures in Android app development.
By the way in every Android Architecture pattern explanation post, I will do my best to show you these issues and how we resolved these with the help of the community.
[Lesson Learned: As an experienced developer you have double or triple responsibility to learn about the environment before going to start work, which theoretically using the same language or concepts which you already know. Otherwise, you can create a problem for business and second, maybe be due to you some of your junior or team fellows start their journey on a wrong path.] ( Thanks ANDROID for the fantastic lesson )
Writing and Reading Code:
This is a general point that is not specific to Android except in case of testing. As a young talented developer. We want to write code. A lot of code. Without taking care of others instead without taking care of ourselves like what will happen if we need to do work again with this code base after three months. In start mostly apps are developed by the solo developers. We start writing code, and in Android, our system contains a lot of ceremony code like XML parsing and finding ids in java. Everything we write with business logic in the same file. Later classes are significantly large, and it’s tough for other’s to find out what is going on in the code. Instead, some times due to God classes original author of the code not able to change with full confidence. So that is the one more point where we need a proper pattern because Android default pattern ( aka MVC ) badly failed.
Second, as you grow in your career, the first thing you learn reading code is more important than writing, or I want to say reading is 3–5 times more important than writing. In the case of Android, we are writing code in one file (Activity) which starts making things tough in reading. Instead, I remember we used to say this file contains everything related to login, signup (FB, G+, Email ). So its easy to find out but that is a huge problem. First, every time we want to change something inside we need to jump a lot from one method to another and then If I want to go back I need to start again because I already forgot from where I started. In simple words, we can say every time we open that file we need to learn how things are working. That consumed a lot of time to fix small issues. That is the point where we feel to create some pattern which will give you a one-time learning curve. Second, if you are not a solo developer on the project then every feature code may contain there own learning curve. So you are not able to say, now I know how one feature code is working I can fix any issue in any other feature code. Your codebase looks like a Universe. Every code file is a different planet.
[ Lesson Learned: On this point I learned, conceptual duplication is good, but code duplication is bad. If you already know some pattern like MVP. Every feature is conceptually duplicating the same concept. For example, my code base contains Profile Presenter and Login Presenter. So this conceptual duplication is impressive.]
So we need to find out some conceptual duplication for our codebases. That will make things easy, the best part which I mostly enjoyed after onboarding of your new team member, he/she can jump to any feature code file, and by seeing same conceptual duplication he/she can add or fix the issue. Because now every file is not a different planet instead that is conceptually the same planet.
Testing Code:
If you ask me one point due to which we evolved our Android Architecture Patterns a lot, I will say testing. Unit testing is tough on Android because Android used JDK API’s with Android SDK API’s. So we are not able to write unit tests without Android API’s. That is a huge problem especially in the perspective of speed and time. Also bad news for TDD lovers, they are always waiting to complete tests so they can play red, green, blue. So I have a feeling on this point community start thinking how we can decouple the Android API’s from Java API’s, and we can run our tests on JVM only, independently from Android without emulators. This is the point where we as a community say Goodbye to MVC 🙁 and we did welcome 🙂 to MVP, MVVM, MVI, or any pattern which can decouple our Android API’s from Java API’s.
[ Lesson Learned: This is the point where I learned some time same patterns we can use in different ways in a different environment by doing some small changes according to the new environment. Like I find out a simple trick in code reviews. Try to find out Android API usage in Presenter, or ViewModel, and you will know the author of the code know about the pattern, but he doesn’t understand the environment why we are using this pattern and how we should use this pattern. So there are some simple differences which you need to find out, and later these are the tips for others to learn things in simple steps. Like you want to achieve MVP, always remember in any case you are not allowed to use any Android API in Presenter instead create an abstraction by using interface and delegate that work through your interface method to talk with Android API. That will resolve a 50–60% learning curve for newcomers.]
Focused Learning Curve:
This is the last point in my opinion due to which we evolved our Architecture patterns or common best practices a lot. I am going to start this section with a question.
For example, we are in the interview room, and an interviewer asks me a question.
Do you know MVP, MVVM, Dagger2, Retrofit, RxJava2, Kotlin?
OR
Do you know how to work on a codebase where you will get a lot of surprises on a daily bases, you never know where you need to learn some new concept in between of a task?
For me, the first question is fantastic, focused and without any confusion but the second one is scary. I can say as a reply yes, but I am not feeling confident.
So that is one point which I really enjoy in the evolution of Android Architecture Patterns because we try to make a lot of things common for everyone who wants to work on Android as a community and every developer can get an equal job opportunity. Business can grow fast because the learning curve is focused and generally all community members know what you need to learn so we have more resources in the market.
The onboarding process is natural for us. We can design a tutorial or exercises for our new team member. Once they complete that exercise, they can go anywhere in our codebase to implement new features or fix issues.
There are a lot of benefits which I can explain here, but I think I need to stop here.
Conclusion:
I hope you guys enjoy this theory and I feel this is the minimum essential points which we should know before going to jump in to practice.
So guys ready, we will meet in the second part of this series soon. Bye Have a nice weekend.
[Note: I have a lot of respect for everyone. So if someone doesn’t agree with my point of view that will be acceptable instead, we can discuss more. ]