bad internet
old phones
best practices
Jacques Smuts
Android Developer
Nomanini


Section | Estimate |
---|---|
Nomanini/Environment | 2:00 |
Bad Internet | 12:00 |
Unexpected Intermission | 1:00 |
Old Phones | 10:00 |
Theme | 6:00 |
Questions | 8:00 |
environment
informal merchants in Africa


Abidjan, Cote d'Ivoire
Dar Es Salaam, Tanzania

Tanzania, further out

Tanzania, further out

Example Phone

bad internet
Many Suggestions linked at the end
- increase timeout
OkHttpClient.Builder()
.connectTimeout(60, TimeUnit.SECONDS)
.writeTimeout(120, TimeUnit.SECONDS)
.readTimeout(120, TimeUnit.SECONDS)
.build()
bad internet
- increase timeout
OkHttpClient.Builder()
.connectTimeout(serverConfig.timeout, TimeUnit.SECONDS)
.writeTimeout(serverConfig.timeout, TimeUnit.SECONDS)
.readTimeout(serverConfig.timeout, TimeUnit.SECONDS)
.build()
bad internet
- increase timeout
- aggressive retry policy?
bad internet
class RetryAndFollowUpInterceptor(private val client: OkHttpClient) : Interceptor {
...
companion object {
/**
* How many redirects and auth challenges should we attempt?
*/
private const val MAX_FOLLOW_UPS = ?
}
}
OkHttp Default
- increase timeout
- aggressive retry policy?
bad internet
class RetryAndFollowUpInterceptor(private val client: OkHttpClient) : Interceptor {
...
companion object {
/**
* How many redirects and auth challenges should we attempt?
*/
private const val MAX_FOLLOW_UPS = 20
}
}
OkHttp Default

































IDEMPOTENT
Running the same operation N times
always gives the same output*
HTTP Method | Idempotent? |
---|---|
GET |
YES |
DELETE | YES |
PUT | YES |
POST | NO |
HTTP Method | Idempotent? |
---|---|
GET | YES |
DELETE | YES |
PUT | YES |
POST | YES |
- aggressive retry policy?
bad internet
api.sellAirtime(
userId = "Biko46",
amount = 300,
productId = "MTN123",
)
- aggressive retry policy!
bad internet
api.sellAirtime(
userId = "Biko46",
amount = 300,
productId = "MTN123",
sourceReference =
generateSourceReference(
"Biko46",
300,
"MTN123"
)
)
- aggressive retry policy!
bad internet
fun generateSourceReference(
userId: String,
amount: Int,
productId: String
) {
val time = System.currentTimeMillis()
return HashUtil.sha1(
"$userId$amount$productId$time"
)
}








































- increase timeout
- aggressive retry policy!
bad internet
- asynchronous architecture
(offline first)
bad internet
- asynchronous architecture





Repository
Database
Cloud/Server
UI / Viewmodel

WorkManager,
PushService,
other
Practice without theory is blind.
Theory without practice is sterile.
- Karl Marx




You need to actually use your app in bad circumstances.
Old Phones
minSdk=15

minSdk=15

minSdk=15

minSdk=15
- Various Libraries Require minSdk19/21
- Compose
- OkHttp 4
- Coil
- Firebase 20+
- Many More
Development Implications
minSdk=15
SECURITY CONCERNS
minSdk=15
- Slow CPU
- Low Memory
- Low Storage Space
- Small Screens
- Unresponsive screen input
- Unexpected bugs
Phone Implications
Slow CPU
minSdk=15

Low Memory
minSdk=15

And LeakCanary!
Small Screens
minSdk=15
Design well, please
Unresponsive Touchscreens
minSdk=15

Chonky Design
Unexpected Bugs
minSdk=15
Slow rollout
Track Crashes
What works for me
- Kotlin
- Coroutines + Flow + Turbine
- Dagger
- SqlDelight
- OkHttp (+ Retrofit + Moshi)
- Repository Pattern
- MVVM/MVI (or similar)
- Flowbinding
Practice without theory is blind.
Theory without practice is sterile.
- Karl Marx
Follow Best Practices,
but harsher
How do I prepare my code
for harsh environments?
How to find best practices?
developer.android.com recommendations
Following open source contributors on social media
Open Source Projects
Coding personal projects
Questions
Further Reading & Tips@
JacquesSmuts.com
