В процесі розробки Android-додатка, який проводить тести на мобільних мережах, таких як дзвінки, SMS, завантаження даних тощо, виникла проблема з аварійним завершенням додатка при спробі завантаження файлу з Інтернету. Початково додаток аварійно завершувався через помилку NetworkOnMainThreadException, яка виникала при спробі використати бібліотеку okhttp3 в головному потоці. Цю проблему було вирішено шляхом використання viewModelScope.launch у SharedViewModel, щоб виконати операції в іншому потоці і уникнути блокування головного потоку.
Однак після вирішення проблеми з NetworkOnMainThreadException додаток продовжував аварійно завершуватися без надання конкретної інформації щодо причин. Лог додатка містив наступну інформацію про помилку:
1 |
2024-02-29 21:29:05.266 6344-6344 AndroidRuntime com.giorgio.roamingqosapp E FATAL EXCEPTION: main Process: com.giorgio.roamingqosapp, PID: 6344 2024-02-29 21:29:05.288 1297-2676 ActivityTaskManager system_server W Force finishing activity com.giorgio.roamingqosapp/.MainActivity |
Після аналізу коду додатка було виявлено, що проблема полягала в спробі викликати операції мережі з головного потоку, що призводило до завершення додатка. Щоб вирішити цю проблему, було важливо виконувати операції мережі асинхронно з головного потоку. Для цього було використано відповідні конструкції в коді додатка, такі як ViewModel та CoroutineScope, для запуску операцій у фоновому режимі.
Для досягнення асинхронності під час завантаження файлу з Інтернету була використана бібліотека OkHttp разом з Kotlin Coroutines. Для цього була створена відповідна функція у класі MyDownloader:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class MyDownloader() { suspend fun makeRequest(fileUrl : String): String { val okHttpClient = OkHttpClient() return withContext(Dispatchers.IO) { parseResponse(okHttpClient.newCall(createRequest(fileUrl)).execute()) } } private fun createRequest(fileUrl: String): Request { return Request.Builder() .url(fileUrl) .build() } private fun parseResponse(response: Response): String { val body = response.body?.string() ?: "" return body } } |
Після внесення цих змін додаток більше не аварійно завершувався при спробі завантаження файлу з Інтернету, а замість цього успішно виконував запити мережі та отримував відповіді.
Загалом, розв’язання проблеми з аварійним завершенням додатка при спробі завантаження файлу з Інтернету полягало в правильному управлінні потоками та використанні асинхронних операцій для операцій мережі, щоб уникнути блокування головного потоку та покращити продуктивність додатка.