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