top | item 32375609

Ask HN: Expert Advices for New Learners in Android Kotlin Development?

24 points| stArrow | 3 years ago | reply

As an expert or an experienced developer in Android App Development with Koltin, what are your advices for new learners?

Are there best practices and things we should or should not do?

16 comments

order
[+] muzani|3 years ago|reply
There's a lot of bad practices out there. Android dev is actually a bit ahead of iOS development. The problem is that bad practices are commonplace, and most apps are greatly overengineered. So you end up needing 2 Android devs per 1 iOS dev, when the ratio should be closer to 0.8:1.

Google normally has good advice, but they tend to build to scale to a hundred engineers, and that includes "deprecated" stuff. You can go many times faster when building for only 1-2 Android engineers.

My rule of thumb is that if the example looks more convoluted than without it, it probably is. If it's good technology, the examples should make you think, "Oh shit, this is genius," not, "I'm too stupid to understand this."

Pick things up once something is actually a problem. Things with a fast ROI:

Kotlin: write 40% less code than Java

ViewModels: cleanly separates lifecycle stuff and reduces crashes

Network (Retrofit, volley): no more custom async and no crashes when the API changes a little

Compose: cut down all "recyclerview" code by 50%-80%, and have much more maintainable logic

Things with a negative ROI (feel free to argue for them):

Most architectures, e.g. MVP, VIPER, "clean". Architecture isn't a fixed pattern, it depends on what your app is trying to do. Most of the time it's like an apartment trying to emulate a hotel.

Butterknife: Replaced by Kotlin

Event bus: Replaced by Flow

RxJava: Replaced by Flow

Data binding or view binding: Replaced by Compose

Robolectric. It breaks for obscure reasons, takes forever to run (effectively locking you out of TDD). Espresso works. You shouldn't spend more time fixing tests than fixing code.

Android debugger. Idk, TDD catches plenty of bugs and plopping logs everywhere catches the rest.

Looper/threads: Replace with Coroutines

Some of the older UI things like animations, which might be obsoleted with Compose.

[+] tsss|3 years ago|reply
1. Be very skeptical about anything coming out of the Android UI toolkit team, especially ViewModel, LiveData, Navigation Component and Pagination Component. You can do better.

2. Koin is not a DI framework.

3. Avoid KAPT (at least in development builds). It's slow.

4. If you think about your UI as a state machine, this state machine _must_ be total. For all intents and purposes, any possible input can arrive in any possible state due to how the Android event loop and view callbacks work and you must handle it gracefully.

5. Your app can be killed and state restored, partially restored or not restored at any point in time (yes, even if you disable config change) and you must handle it gracefully.

6. Be mindful of energy saving and background tasks. The logic for background work changes frequently and manufacturers do not abide by the standards.

7. Do not blindly implement MVI or similar architectures because you read about it on the Spotify blog. Read research papers and in-depth material from the web dev community. They're always about 5 years ahead of the Android community.

[+] lawgimenez|3 years ago|reply
- This is a good place to start: https://developer.android.com/courses/android-basics-kotlin/...

- As a beginner I suggest narrowing your learning scope. What I mean is that focus more on developer.android.com and not some outdated material from a blogger and YouTuber. I am currently mentoring an Android beginner and it seems some YouTuber decides to teach him that every variable should be declared static. Yes, imagine the horror when I saw 20 or more static MediaPlayer variables. My point is, it might overwhelm you.

- Stick to the official JetBrains and Android channels for now.

- Keep everything updated. As soon as Android Studio or any third-party library releases an update, download and install it right away. This is much better than keeping everything mostly outdated.

- As a beginner, it's okay to start with MVC architecture. When you get comfortable as you go along, you can invest in learning the more advanced architecture. But MVC is still fine.

- I'm not sure if you want to dig right away with Jetpack Compose, if yes I suggest learn first on the XML layout. It's a good foundation regarding Android UI.

- Familiarize early in your learning the concepts of threading/coroutines.

- Learn Activity lifecycle as much as you can: https://developer.android.com/guide/components/activities/ac...

- Learn Android's Context: https://developer.android.com/reference/android/content/Cont...

I think that's it for now.

[+] charleslmunger|3 years ago|reply
The best pieces of advice that I can share from experience:

Do not do eager work at process startup (application onCreate, content provider onCreate, etc). Your process starts up for many different reasons, and work done there except for a narrow subset (crash reporting setup) is unlikely to apply to all of them. However, once the code is there it's hard to find what else might be depending on it later.

Do not use inheritance to share code. Androids APIs were designed to point you in this direction, but overrides upon overrides will make your life miserable. Once you have a base class from Hilt or AppCompat to provide composition for you (via DI or lifecycle), add no further layers of inheritance.

Avoid the event bus pattern. It was fashionable for a while but it turns the codebase to spaghetti. It tends to make error handling impossible or at least convoluted and debugging is a huge challenge.

[+] sriram_malhar|3 years ago|reply
I'm not an expert android programmer, not a beginner either.

In addition to the useful tips that others have posted, here is one. For every API function or class X that you encounter in an example, google for "X deprecated". It is insane how fast the platform has changed in the span of 2 years.

[+] butz|3 years ago|reply
Don't jump fully into Jetpack Compose yet. While in theory it looks nice, something similar to ReactJS coming from web dev side, there are still a lot of papercuts and not implemented features. Use classic xml layouts, but keep an eye on Compose updates.
[+] h4waii|3 years ago|reply
Why use Kotlin when you can build it in React Native, and get an iOS counterpart for essentially free out of the codebase?

Curious as to why a new learner would go this route.

[+] muzani|3 years ago|reply
RN works great for CRUD apps. But do you really want an app if it's only CRUD? Might as well just make a site or some PWA.

With a lot of apps, you end up dealing with something lower level e.g. EXIF data, bluetooth networking, things like custom calls through the app built on the native call kits.

Plus finer control on the UI & lifecycle. Something like Compose/XML or even Flutter/Dart is built perfectly for mobile interfaces, while with RN it feels like you're wrestling with flexboxes originally designed for desktop. RN supports this stuff, but then you'd still have to learn Kotlin and Swift, so it's not exactly a free ride.

[+] origin_path|3 years ago|reply
Kotlin Multiplatform lets you share code between iOS and Android, writing only the UI code with SwiftUI and the rest is shared. You can also run Compose UI on the desktop so you don't need a web app.
[+] lawgimenez|3 years ago|reply
I will use React Native when it reaches v1.0.
[+] Ologn|3 years ago|reply
I started dabbling in Android App Development in 2009, and did it full-time since 2011. I started using Kotlin a few years ago.

Get familiar with using Android Studio as your IDE. Read the Kotlin and Android documentation. Look at the (newer) Android example apps Google puts up on Github. Watch the (especially more recent) Android Developer videos on Youtube, especially the I/O ones (although some other deep dive ones are good too). Look at the codelabs.

If you're already programming, one thing to be aware of is how ephemeral Android lifecycle classes (Activity, Fragment and associated Views) are. At any time the phone can be shut off and they can go away and be killed, and any state will disappear. So be aware of storing state in ViewModels and this sort of thing.

Also, under the hood android has a Looper and a main thread with a message queue, and handlers. On an API level your Manifest will probably have a start Activity that is the main launcher, and which can launch other activities - but you don't launch them, you send an intent to launch them and then the system launches it. You don't have to understand all of this right off the bat but you do have to understand some of it, including how there is a main (UI) thread, and then you can launch network or disk access or computation calls on other threads.

A statement is easier to fix than a function, a function easier to fix than a class, a class easier to fix than a module, a module easier to fix than the whole app. Getting the architecture right is important, as it is more difficult to clean up later. For a big app people often put network (REST API) access into its own module, put analytics into its own module etc. Plus functions are broken down. If HN had a big app, account might have its own module, submission threads and comments might have its own module, search might have its own module etc. Whatever makes sense. For a small app which won't grow, modularizing like that may be premature.

Also within a module in its internal architecture, MVVM is the main architecture used. Something like clean takes more effort to put in and keep - what does a company do if senior people come in and do not like clean and aren't using use cases or business rules without dependencies etc.? If engineering is not already filled with good senior people committed to clean, who are not taking shortcuts to get features out etc. I would think twice about trying to use clean, for social reasons more than technical reasons.

Android is notoriously difficult to test. Where do you put your tests? There is the testing pyramid of UI/e2e at the top, features/integration in the middle and unit tests at the bottom - the bottom of the period being the most tests. Except you can't really directly unit test Android lifecycle classes like Activity or Fragment with JUnit. So what do you do? You use the Google suggested unidirectional data flow from ViewModels into the lean lifecycle classes, sending in a UI model to the lifecycle classes to create the UI from. You unit test in the ViewModel the various scenarios and edge cases going out to the UI/lifecycle classes. You can unit test in other places but this is a way of indirectly unit testing UI. There are also UI tests like Espresso higher up on the test pyramid.

[+] muzani|3 years ago|reply
Lifecycle is one of those things that earns a native mobile developer's salary. It's the selling point where native beats hybrid, as well as web.

The other might be threading. Kotlin Coroutines and Flow is incredibly powerful and one of the coolest things on any system. I wish this kind of thing was available for servers and such. I'd argue that Looper and Handlers are deprecated once you understand Coroutines and Flow. It's probably one of the things you can skip these days.