Pagkawala ng koneksyon — isa sa mga pinakakaraniwan at nakakainis na pangyayari sa mga mobile application. Nawawalan ng access ang user sa data, naaantala ang operasyon, nag-freeze o nag-crash ang app. Ayon sa Google Android Developer Blog, 70% ng mga user ay nagtatanggal ng app kung ito ay nag-crash o nag-freeze nang dalawang beses. Suriin natin ang mga dahilan ng pagkawala ng koneksyon at mga paraan ng pagbuo ng fault-tolerant na komunikasyon.
Mga Pangunahing Punto
Nadidiskonekta — termino ng user na naglalarawan sa sitwasyon kapag nawalan ng koneksyon ang app sa server, huminto sa pagtugon sa mga aksyon, o nagtatapos sa isang error. Sa teknikal na kahulugan, ito ay maaaring: error sa network (timeout, DNS failure), ANR (pag-block ng UI thread), crash (hindi nahawakang exception) o race condition (kondisyon ng karera).
Para sa user, lahat ng mga senaryong ito ay pareho ang hitsura: humihinto ang app sa paggana. Ang pagkakaiba para sa developer ay nasang diskarte sa diagnosis at pag-aayos. Ang mga error sa network ay nireresolba ng mga mekanismo ng retry, ANR — sa pamamagitan ng paglipat ng mga operasyon palabas ng UI thread, crash — sa pamamagitan ng paghawak ng exception.
Ayon sa Crittercism (ngayon Apteligent), ang karaniwang mobile app ay nawawalan ng 1-2% ng mga user nito sa bawat crash. Para sa isang app na may 1 milyong user, ito ay 10-20 libong nawalang pag-install bawat isang bug. Ito ay lalong kritikal para sa mga app sa sektor ng pananalapi at medikal.
Hindi matatag na network — ang mga mobile device ay patuloy na lumilipat sa pagitan ng Wi-Fi at mobile network, pumapasok sa mga zone na walang coverage (metro, elevator, basement). Ang bawat paglipat ay nagdudulot ng pansamantalang pagkawala ng koneksyon na dapat hawakan nang tama ng app.
Mga time-out — kung hindi tumugon ang server sa itinakdang oras (karaniwang 10-30 segundo), ang client ay nagtatapon ng SocketTimeoutException. Ang mahabang time-out na walang feedback ay itinuturing ng user bilang freeze. Inirerekomenda na itakda ang time-out nang hindi hihigit sa 15 segundo.
val client = OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build()
Kondisyon ng karera (race condition) — nangyayari kapag maraming thread ang sabay na nagbabasa at nagsusulat ng parehong data nang walang synchronization. Halimbawa, ang pag-load ng data mula sa cache sa UI thread nang kahanay sa pag-update ng cache mula sa network ay maaaring humantong sa pagpapakita ng luma o hindi tamang data.
Offline-first — pattern ng arkitektura kung saan ang lokal na imbakan (Room, CoreData) ay ang tanging pinagmumulan ng katotohanan. Ang network ay ginagamit para sa pag-sync ng data sa background. Ang user ay palaging nakakakita ng napapanahong data mula sa lokal na cache, kahit na walang network.
Repository pattern — nag-iisang entry point para sa data na nagpapasya kung kukuha ng data mula sa network o cache. Ang repository ay nag-aabstrak ng pinagmulan ng data mula sa ViewModel at UI. Sa error sa network, ang repository ay awtomatikong lumilipat sa lokal na pinagmulan.
class UserRepository(
private val api: UserApi,
private val dao: UserDao
) {
suspend fun getUsers(): Result<List<User>> {
return try {
val remote = api.fetchUsers()
dao.insertAll(remote)
Result.success(remote)
} catch (e: IOException) {
val cached = dao.getAll()
if (cached.isNotEmpty()) {
Result.success(cached) // ibalik ang cache sa error sa network
} else {
Result.failure(e)
}
}
}
}
Circuit Breaker — pattern ng proteksyon ng server mula sa baha ng mga kahilingan kapag hindi magagamit. Pagkatapos ng N sunod-sunod na error, bubukas ang switch at lahat ng kahilingan ay agad na nagbabalik ng error nang walang pagtatangkang kumonekta. Pagkatapos ng isang tiyak na time-out, ang switch ay pupunta sa half-open na estado para sa isang pagsubok na kahilingan.
Exponential backoff — karaniwang mekanismo ng retry. Pagkatapos ng unang pagkabigo maghintay ng 1 segundo, pagkatapos ng pangalawa — 2 segundo, pagkatapos 4, 8, 16. Limitahan ang maximum na bilang ng mga pagtatangka (karaniwang 3-5) upang hindi ma-overload ang server at baterya.
Feedback ng user — sa error sa network magpakita ng naiintindihang mensahe: "Walang koneksyon", "Pansamantalang hindi available ang server", "Suriin ang internet". Gumamit ng Snackbar o Inline State View. Huwag kailanman magpakita ng mga teknikal na error (HTTP 500, SocketException) sa user.
ConnectivityManager — Android API para sa pag-monitor ng network. Pahintulutan ang app na tumugon sa mga pagbabago: sa pagkawala ng network magpakita ng placeholder, sa pagpapanumbalik — awtomatikong i-update ang data. Sa iOS gamitin ang NWPathMonitor mula sa Network framework.
class NetworkMonitor(private val context: Context) {
private val manager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
fun isOnline(): Boolean {
val network = manager.activeNetwork ?: return false
val caps = manager.getNetworkCapabilities(network) ?: return false
return caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
}
}
Crashlytics (Firebase) — karaniwang tool sa pag-uulat ng crash para sa mga mobile app. Kinokolekta ang stacktrace ng lahat ng hindi nahahawakang exception, bersyon ng OS, modelo ng device at oras ng crash. Pinapayagan ang pag-grupo ng mga error at pagtatalaga ng mga responsable para sa pag-aayos.
Sentry — alternatibo sa Crashlytics na may suporta sa pag-monitor ng performance. Pinapayagan ang pag-trace ng mga partikular na transaksyon (hal., "pagpapatunay ng user") at makita kung saang hakbang naganap ang error. Performance tracing ay tumutulong na makilala ang mga network time-out mula sa mga bug sa lohika ng app.
Timber — library ng pag-log para sa Android na may awtomatikong pagdaragdag ng mga tag ayon sa klase. Sa debug build, i-log ang lahat ng network request at response. Sa release build — mga error at babala lamang sa pamamagitan ng Crashlytics.setCustomLog.
| Tool | Uri | Kailan gagamitin |
|---|---|---|
| Crashlytics | Crash reporting | Palagi sa release — awtomatikong pagkokolekta ng mga crash |
| Sentry | Crash + Performance | Kapag kailangan i-profile ang mga partikular na senaryo ng user |
| Timber | Logging | Debug: kumpletong pag-log; Release: mga error lamang |
| HTTP Toolkit | Network debug | Lokal na pag-intercept at pagsusuri ng trapiko ng HTTP |
Ayon sa Firebase Summit 2023, ang mga app na nagpatupad ng Crashlytics + Performance Monitoring ay nagbabawas ng average na oras ng pagtuklas at pag-aayos ng mga kritikal na bug mula 3 araw hanggang 4 na oras. Inirerekomenda na mag-set up ng mga alert sa bawat crash na may dalas na higit sa 0.1% ng mga aktibong user.
Mga Madalas Itanong
Kung ang crash ay hindi nahuhuli sa Crashlytics, suriin ang native crash (SIGSEGV, SIGABRT) — hindi ito pinoproseso ng Java/Kotlin exception handler. Sa Android ito ay maaaring pagtagas ng native memory mula sa JNI, sa iOS — EXC_BAD_ACCESS. Gumamit ng Breakpad (Android) o PLCrashReporter (iOS) para sa pagkolekta ng stacktrace ng native crash.
Gumamit ng Network Link Conditioner (naka-built in sa iOS, para sa Android mayroong Facebook Network Connection Class o mga setting ng Developer Options > Network > Select network type). Itakda ang pagkaantala sa 500-3000 ms at pagkawala ng packet sa 5-30%. Maaari ring gumamit ng Charles Proxy o mitmproxy para sa pag-emulate ng mga pagkaantala sa network at pagkakadiskonekta.
ANR ay nangyayari kapag ang UI thread ay naka-block nang higit sa 5 segundo. Ang mga kahilingan sa network ay dapat isagawa sa background thread: coroutines (viewModelScope.launch(Dispatchers.IO)), RxJava (subscribeOn(Schedulers.io)) o WorkManager para sa pag-sync. Palaging magtakda ng mga time-out sa HTTP client — ang kawalan ng time-out ay maaaring humantong sa walang hanggang pag-block.
Race condition — sitwasyon kung saan ang resulta ng operasyon ay nakadepende sa pagkakasunod-sunod ng pagpapatupad ng mga thread. Halimbawa, ang user ay mabilis na pumindot ng button na "Ipadala" nang dalawang beses at ang kahilingan ay naipadala nang dalawang beses. Solusyon: gumamit ng Mutex, single-threaded executors o state machine (i-disable ang button pagkatapos ng unang pindot). Sa Kotlin gumamit ng Mutex mula sa coroutines o @Synchronized na anotasyon.
Ilapat ang Chaos Engineering para sa mga mobile app: patayin ang network sa panahon ng mga operasyon, gayahin ang mataas na pagkaantala, lumipat sa pagitan ng Wi-Fi at mobile network, patayin ang proseso ng system. Mga tool: Facebook Network Connection Class, Charles Proxy, iOS Network Link Conditioner. Sa CI/CD magdagdag ng mga UI test na may iba't ibang kondisyon ng network sa pamamagitan ng AndroidTest Orchestrator.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din