mirror of
https://github.com/kiwix/kiwix-android.git
synced 2025-08-02 18:26:23 -04:00
Refactored RxJava
to coroutines
in ConnectivityBroadcastReceiver
.
* Simplified the `combineToLanguageList` method and removed warnings. * Refactored `ZimManageViewModelTest` to align with the changes. * Removed unused `RxJava` code from the project. * Removed all `RxJava` dependencies from the project. * Updated the `README` file to reflect that `RxJava` is no longer used. * Updated `credit.html` accordingly, similar to the `README`.
This commit is contained in:
parent
ad62661e67
commit
6cae44821e
@ -103,7 +103,6 @@ This variable should only be set when building an APK. If you set this variable
|
||||
- 🔄 [Retrofit](https://square.github.io/retrofit/) - Turns REST API into a Java interface.
|
||||
- 🌐 [OkHttp](https://github.com/square/okhttp) - HTTP client for Android and Java.
|
||||
- 🎭 [Mockito](https://github.com/mockito/mockito) - Mocking framework for unit tests.
|
||||
- ⚡ [RxJava](https://github.com/ReactiveX/RxJava) - Reactive Extensions for the JVM.
|
||||
- 🗃️ [ObjectBox](https://github.com/objectbox/objectbox-java) - Reactive NoSQL Database.
|
||||
- 🐒 [MockK](https://github.com/mockk/mockk) - Kotlin mocking library.
|
||||
- 🧪 [JUnit5](https://github.com/junit-team/junit5/) - Next-generation JUnit.
|
||||
|
2
app/proguard-rules.pro
vendored
2
app/proguard-rules.pro
vendored
@ -91,5 +91,3 @@
|
||||
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
|
||||
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
|
||||
-dontwarn org.openjsse.net.ssl.OpenJSSE
|
||||
|
||||
-keep class io.reactivex.** { *; }
|
||||
|
@ -87,11 +87,6 @@ Translatewiki community<br>
|
||||
<br/>
|
||||
Copyright 2013 Square, Inc.
|
||||
</li>
|
||||
<li>
|
||||
<b>RxAndroid</b>
|
||||
<br/>
|
||||
Copyright 2015 RxAndroid Authors
|
||||
</li>
|
||||
<li>
|
||||
<b>Fetch</b>
|
||||
<br/>
|
||||
|
@ -54,7 +54,6 @@ import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.retry
|
||||
import kotlinx.coroutines.flow.take
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.reactive.asFlow
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
@ -302,7 +301,6 @@ class ZimManageViewModel @Inject constructor(
|
||||
}
|
||||
coroutineJobs.clear()
|
||||
context.unregisterReceiver(connectivityBroadcastReceiver)
|
||||
connectivityBroadcastReceiver.stopNetworkState()
|
||||
appProgressListener = null
|
||||
super.onCleared()
|
||||
}
|
||||
@ -393,8 +391,7 @@ class ZimManageViewModel @Inject constructor(
|
||||
library: MutableSharedFlow<LibraryNetworkEntity>,
|
||||
dispatcher: CoroutineDispatcher = Dispatchers.IO
|
||||
) = requestDownloadLibrary.flatMapConcat {
|
||||
connectivityBroadcastReceiver.networkStates.asFlow()
|
||||
.distinctUntilChanged()
|
||||
connectivityBroadcastReceiver.networkStates
|
||||
.filter { networkState -> networkState == CONNECTED }
|
||||
.take(1)
|
||||
.flatMapConcat {
|
||||
@ -455,8 +452,6 @@ class ZimManageViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
private fun updateNetworkStates() = connectivityBroadcastReceiver.networkStates
|
||||
.asFlow()
|
||||
.catch { it.printStackTrace() }
|
||||
.onEach { state -> networkStates.postValue(state) }
|
||||
.launchIn(viewModelScope)
|
||||
|
||||
@ -531,21 +526,25 @@ class ZimManageViewModel @Inject constructor(
|
||||
booksFromNetwork: List<Book>,
|
||||
allLanguages: List<Language>
|
||||
) = when {
|
||||
booksFromNetwork.isEmpty() && allLanguages.isEmpty() -> defaultLanguage()
|
||||
booksFromNetwork.isEmpty() && allLanguages.isNotEmpty() -> emptyList()
|
||||
booksFromNetwork.isNotEmpty() && allLanguages.isEmpty() ->
|
||||
booksFromNetwork.isEmpty() -> {
|
||||
if (allLanguages.isEmpty()) {
|
||||
defaultLanguage()
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
allLanguages.isEmpty() ->
|
||||
fromLocalesWithNetworkMatchesSetActiveBy(
|
||||
networkLanguageCounts(booksFromNetwork),
|
||||
defaultLanguage()
|
||||
)
|
||||
|
||||
booksFromNetwork.isNotEmpty() && allLanguages.isNotEmpty() ->
|
||||
else ->
|
||||
fromLocalesWithNetworkMatchesSetActiveBy(
|
||||
networkLanguageCounts(booksFromNetwork),
|
||||
allLanguages
|
||||
)
|
||||
|
||||
else -> throw RuntimeException("Impossible state")
|
||||
}
|
||||
|
||||
private fun networkLanguageCounts(booksFromNetwork: List<Book>) =
|
||||
|
@ -33,7 +33,6 @@ import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.verify
|
||||
import io.reactivex.processors.PublishProcessor
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@ -44,6 +43,7 @@ import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.coroutines.test.setMain
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
@ -125,7 +125,7 @@ class ZimManageViewModelTest {
|
||||
private val languages = MutableStateFlow<List<Language>>(emptyList())
|
||||
private val fileSystemStates =
|
||||
MutableStateFlow<FileSystemState>(FileSystemState.DetectingFileSystem)
|
||||
private val networkStates: PublishProcessor<NetworkState> = PublishProcessor.create()
|
||||
private val networkStates = MutableStateFlow(NetworkState.NOT_CONNECTED)
|
||||
private val booksOnDiskListItems = MutableStateFlow<List<BooksOnDiskListItem>>(emptyList())
|
||||
private val testDispatcher = StandardTestDispatcher()
|
||||
|
||||
@ -170,6 +170,7 @@ class ZimManageViewModelTest {
|
||||
languages.value = emptyList()
|
||||
fileSystemStates.value = FileSystemState.DetectingFileSystem
|
||||
booksOnDiskListItems.value = emptyList()
|
||||
networkStates.value = NOT_CONNECTED
|
||||
viewModel =
|
||||
ZimManageViewModel(
|
||||
downloadRoomDao,
|
||||
@ -386,18 +387,17 @@ class ZimManageViewModelTest {
|
||||
coEvery { kiwixService.getLibrary() } returns libraryNetworkEntity(networkBooks)
|
||||
every { defaultLanguageProvider.provide() } returns defaultLanguage
|
||||
viewModel.networkLibrary.emit(libraryNetworkEntity(networkBooks))
|
||||
advanceUntilIdle()
|
||||
runCurrent()
|
||||
languages.value = dbBooks
|
||||
advanceUntilIdle()
|
||||
networkStates.onNext(CONNECTED)
|
||||
runCurrent()
|
||||
networkStates.value = CONNECTED
|
||||
advanceUntilIdle()
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun `network states observed`() = runTest {
|
||||
networkStates.offer(NOT_CONNECTED)
|
||||
networkStates.tryEmit(NOT_CONNECTED)
|
||||
advanceUntilIdle()
|
||||
viewModel.networkStates.test()
|
||||
.assertValue(NOT_CONNECTED)
|
||||
@ -414,15 +414,20 @@ class ZimManageViewModelTest {
|
||||
triggerAction = {
|
||||
every { application.getString(any()) } returns ""
|
||||
every { application.getString(any(), any()) } returns ""
|
||||
networkStates.onNext(CONNECTED)
|
||||
downloads.value = listOf(downloadModel(book = bookDownloading))
|
||||
books.value = listOf(bookOnDisk(book = bookAlreadyOnDisk))
|
||||
languages.value =
|
||||
networkStates.tryEmit(CONNECTED)
|
||||
advanceUntilIdle()
|
||||
downloads.tryEmit(listOf(downloadModel(book = bookDownloading)))
|
||||
advanceUntilIdle()
|
||||
books.tryEmit(listOf(bookOnDisk(book = bookAlreadyOnDisk)))
|
||||
advanceUntilIdle()
|
||||
languages.tryEmit(
|
||||
listOf(
|
||||
language(isActive = true, occurencesOfLanguage = 1, languageCode = "activeLanguage"),
|
||||
language(isActive = false, occurencesOfLanguage = 1, languageCode = "inactiveLanguage")
|
||||
)
|
||||
fileSystemStates.value = CanWrite4GbFile
|
||||
)
|
||||
fileSystemStates.tryEmit(CanWrite4GbFile)
|
||||
advanceUntilIdle()
|
||||
viewModel.networkLibrary.emit(
|
||||
libraryNetworkEntity(
|
||||
listOf(
|
||||
@ -450,7 +455,6 @@ class ZimManageViewModelTest {
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@Test
|
||||
fun `library marks files over 4GB as can't download if file system state says to`() = runTest {
|
||||
val bookOver4Gb =
|
||||
@ -464,14 +468,15 @@ class ZimManageViewModelTest {
|
||||
testFlow(
|
||||
viewModel.libraryItems,
|
||||
triggerAction = {
|
||||
networkStates.onNext(CONNECTED)
|
||||
downloads.value = listOf()
|
||||
books.value = listOf()
|
||||
languages.value =
|
||||
networkStates.tryEmit(CONNECTED)
|
||||
downloads.tryEmit(listOf())
|
||||
books.tryEmit(listOf())
|
||||
languages.tryEmit(
|
||||
listOf(
|
||||
language(isActive = true, occurencesOfLanguage = 1, languageCode = "activeLanguage")
|
||||
)
|
||||
fileSystemStates.value = CannotWrite4GbFile
|
||||
)
|
||||
fileSystemStates.tryEmit(CannotWrite4GbFile)
|
||||
viewModel.networkLibrary.emit(libraryNetworkEntity(listOf(bookOver4Gb)))
|
||||
},
|
||||
assert = {
|
||||
|
@ -20,9 +20,6 @@ object Libs {
|
||||
"org.jetbrains.kotlinx:kotlinx-coroutines-android:" +
|
||||
Versions.org_jetbrains_kotlinx_kotlinx_coroutines
|
||||
|
||||
const val kotlinx_coroutines_rx3: String =
|
||||
"org.jetbrains.kotlinx:kotlinx-coroutines-rx3:" + Versions.kotlinx_coroutines_rx3
|
||||
|
||||
/**
|
||||
* https://github.com/Kotlin/kotlinx.coroutines
|
||||
*/
|
||||
@ -66,12 +63,6 @@ object Libs {
|
||||
|
||||
const val tracing: String = "androidx.tracing:tracing:" + Versions.tracing
|
||||
|
||||
/**
|
||||
* https://github.com/square/retrofit
|
||||
*/
|
||||
const val adapter_rxjava2: String = "com.squareup.retrofit2:adapter-rxjava2:" +
|
||||
Versions.com_squareup_retrofit2
|
||||
|
||||
/**
|
||||
* https://github.com/square/retrofit
|
||||
*/
|
||||
@ -189,11 +180,6 @@ object Libs {
|
||||
*/
|
||||
const val objectbox_kotlin: String = "io.objectbox:objectbox-kotlin:" + Versions.io_objectbox
|
||||
|
||||
/**
|
||||
* https://objectbox.io
|
||||
*/
|
||||
const val objectbox_rxjava: String = "io.objectbox:objectbox-rxjava:" + Versions.io_objectbox
|
||||
|
||||
/**
|
||||
* http://mockk.io
|
||||
*/
|
||||
@ -301,11 +287,6 @@ object Libs {
|
||||
*/
|
||||
const val appcompat: String = "androidx.appcompat:appcompat:" + Versions.appcompat
|
||||
|
||||
/**
|
||||
* https://github.com/ReactiveX/RxAndroid
|
||||
*/
|
||||
const val rxandroid: String = "io.reactivex.rxjava2:rxandroid:" + Versions.rxandroid
|
||||
|
||||
/**
|
||||
* https://developer.android.com/jetpack/androidx
|
||||
*/
|
||||
@ -327,11 +308,6 @@ object Libs {
|
||||
|
||||
const val barista: String = "com.adevinta.android:barista:" + Versions.barista
|
||||
|
||||
/**
|
||||
* https://github.com/ReactiveX/RxJava
|
||||
*/
|
||||
const val rxjava: String = "io.reactivex.rxjava2:rxjava:" + Versions.rxjava
|
||||
|
||||
/**
|
||||
* https://developer.android.com/jetpack/androidx
|
||||
*/
|
||||
@ -348,8 +324,6 @@ object Libs {
|
||||
|
||||
const val roomRuntime = "androidx.room:room-runtime:" + Versions.roomVersion
|
||||
|
||||
const val roomRxjava2 = "androidx.room:room-rxjava2:" + Versions.roomVersion
|
||||
|
||||
/**
|
||||
* https://github.com/zxing/zxing
|
||||
*/
|
||||
@ -387,9 +361,6 @@ object Libs {
|
||||
|
||||
const val COMPOSE_UI_MANIFEST = "androidx.compose.ui:ui-test-manifest:${Versions.COMPOSE_VERSION}"
|
||||
|
||||
const val COMPOSE_RX_JAVA2 =
|
||||
"androidx.compose.runtime:runtime-rxjava2:${Versions.COMPOSE_VERSION}"
|
||||
|
||||
const val COMPOSE_LIVE_DATA =
|
||||
"androidx.compose.runtime:runtime-livedata:${Versions.COMPOSE_VERSION}"
|
||||
}
|
||||
|
@ -16,8 +16,6 @@ object Versions {
|
||||
|
||||
const val org_jetbrains_kotlinx_kotlinx_coroutines: String = "1.10.1"
|
||||
|
||||
const val kotlinx_coroutines_rx3: String = "1.10.1"
|
||||
|
||||
const val androidx_test_espresso: String = "3.6.1"
|
||||
|
||||
const val tracing: String = "1.2.0"
|
||||
@ -86,8 +84,6 @@ object Versions {
|
||||
|
||||
const val appcompat: String = "1.7.0"
|
||||
|
||||
const val rxandroid: String = "2.1.1"
|
||||
|
||||
const val core_ktx: String = "1.15.0"
|
||||
|
||||
const val androidx_activity: String = "1.9.3"
|
||||
@ -100,8 +96,6 @@ object Versions {
|
||||
|
||||
const val barista: String = "4.3.0"
|
||||
|
||||
const val rxjava: String = "2.2.21"
|
||||
|
||||
const val webkit: String = "1.12.1"
|
||||
|
||||
const val junit: String = "1.1.5"
|
||||
|
@ -214,7 +214,6 @@ class AllProjectConfigurer {
|
||||
androidTestImplementation(Libs.navigation_testing)
|
||||
implementation(Libs.logging_interceptor)
|
||||
implementation(Libs.retrofit)
|
||||
implementation(Libs.adapter_rxjava2)
|
||||
testImplementation(Libs.junit_jupiter)
|
||||
testImplementation(Libs.mockk)
|
||||
testImplementation(Libs.assertj_core)
|
||||
@ -228,13 +227,10 @@ class AllProjectConfigurer {
|
||||
implementation(Libs.core_ktx)
|
||||
implementation(Libs.fragment_ktx)
|
||||
implementation(Libs.collection_ktx)
|
||||
implementation(Libs.rxandroid)
|
||||
implementation(Libs.rxjava)
|
||||
implementation(Libs.preference_ktx)
|
||||
implementation(Libs.roomKtx)
|
||||
annotationProcessor(Libs.roomCompiler)
|
||||
implementation(Libs.roomRuntime)
|
||||
implementation(Libs.roomRxjava2)
|
||||
kapt(Libs.roomCompiler)
|
||||
implementation(Libs.tracing)
|
||||
implementation(Libs.fetch)
|
||||
@ -246,15 +242,12 @@ class AllProjectConfigurer {
|
||||
implementation(Libs.COMPOSE_MATERIAL3)
|
||||
implementation(Libs.ANDROIDX_ACTIVITY_COMPOSE)
|
||||
implementation(Libs.COMPOSE_TOOLING_PREVIEW)
|
||||
implementation(Libs.COMPOSE_RX_JAVA2)
|
||||
implementation(Libs.COMPOSE_LIVE_DATA)
|
||||
|
||||
// Compose UI test implementation
|
||||
androidTestImplementation(Libs.COMPOSE_UI_TEST_JUNIT)
|
||||
debugImplementation(Libs.COMPOSE_UI_MANIFEST)
|
||||
debugImplementation(Libs.COMPOSE_TOOLING)
|
||||
|
||||
implementation(Libs.kotlinx_coroutines_rx3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +58,6 @@ dependencies {
|
||||
|
||||
implementation(Libs.android_arch_lifecycle_extensions)
|
||||
implementation(Libs.objectbox_kotlin)
|
||||
implementation(Libs.objectbox_rxjava)
|
||||
implementation(Libs.webkit)
|
||||
testImplementation(Libs.kotlinx_coroutines_test)
|
||||
implementation(Libs.kotlinx_coroutines_android)
|
||||
|
@ -21,30 +21,27 @@ package org.kiwix.kiwixmobile.core.zim_manager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.ConnectivityManager
|
||||
import io.reactivex.Flowable
|
||||
import io.reactivex.processors.BehaviorProcessor
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import org.kiwix.kiwixmobile.core.base.BaseBroadcastReceiver
|
||||
import org.kiwix.kiwixmobile.core.networkState
|
||||
import javax.inject.Inject
|
||||
|
||||
class ConnectivityBroadcastReceiver @Inject constructor(
|
||||
private val connectivityManager: ConnectivityManager
|
||||
) :
|
||||
BaseBroadcastReceiver() {
|
||||
@Suppress("DEPRECATION")
|
||||
override val action: String = ConnectivityManager.CONNECTIVITY_ACTION
|
||||
) : BaseBroadcastReceiver() {
|
||||
@Suppress("DEPRECATION")
|
||||
override val action: String = ConnectivityManager.CONNECTIVITY_ACTION
|
||||
|
||||
private val _networkStates = BehaviorProcessor.createDefault(connectivityManager.networkState)
|
||||
val networkStates: Flowable<NetworkState> = _networkStates
|
||||
|
||||
override fun onIntentWithActionReceived(
|
||||
context: Context,
|
||||
intent: Intent
|
||||
) {
|
||||
_networkStates.onNext(connectivityManager.networkState)
|
||||
}
|
||||
|
||||
fun stopNetworkState() {
|
||||
_networkStates.onComplete()
|
||||
}
|
||||
private val _networkStates = MutableStateFlow(NetworkState.NOT_CONNECTED).apply {
|
||||
tryEmit(connectivityManager.networkState)
|
||||
}
|
||||
val networkStates: StateFlow<NetworkState> = _networkStates
|
||||
|
||||
override fun onIntentWithActionReceived(
|
||||
context: Context,
|
||||
intent: Intent
|
||||
) {
|
||||
_networkStates.tryEmit(connectivityManager.networkState)
|
||||
}
|
||||
}
|
||||
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Kiwix Android
|
||||
* Copyright (c) 2019 Kiwix <android.kiwix.org>
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package org.kiwix.sharedFunctions
|
||||
|
||||
import io.reactivex.Scheduler
|
||||
import io.reactivex.android.plugins.RxAndroidPlugins
|
||||
import io.reactivex.plugins.RxJavaPlugins
|
||||
|
||||
fun setScheduler(replacementScheduler: Scheduler) {
|
||||
RxJavaPlugins.setIoSchedulerHandler { scheduler -> replacementScheduler }
|
||||
RxJavaPlugins.setComputationSchedulerHandler { scheduler -> replacementScheduler }
|
||||
RxJavaPlugins.setNewThreadSchedulerHandler { scheduler -> replacementScheduler }
|
||||
RxAndroidPlugins.setInitMainThreadSchedulerHandler { scheduler -> replacementScheduler }
|
||||
}
|
||||
|
||||
fun resetSchedulers() {
|
||||
RxJavaPlugins.reset()
|
||||
RxAndroidPlugins.reset()
|
||||
}
|
@ -88,11 +88,6 @@
|
||||
<br/>
|
||||
Copyright 2013 Square, Inc.
|
||||
</li>
|
||||
<li>
|
||||
<b>RxAndroid</b>
|
||||
<br/>
|
||||
Copyright 2015 RxAndroid Authors
|
||||
</li>
|
||||
<li>
|
||||
<b>Fetch</b>
|
||||
<br/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user