Skip to content

Commit

Permalink
updated dependencies
Browse files Browse the repository at this point in the history
updated gradle version
fixed several leaks in SamaObserverImpl and SamaRvAdapter
  • Loading branch information
stefanosiano committed Sep 11, 2024
1 parent b36672b commit 4b07db3
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 76 deletions.
42 changes: 21 additions & 21 deletions buildSrc/src/main/java/Deps.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
object Deps {

// Sdk versions
const val sdkCompile = 33
const val sdkCompile = 34
const val sdkTarget = sdkCompile
const val sdkMin = 14

private const val agpVersion = "7.3.1"
private const val kotlinVersion = "1.8.0"
private const val coroutinesVersion = "1.6.4"
private const val espressoVersion = "3.5.0"
private const val roomVersion = "2.4.3"
const val detektPluginVersion = "1.19.0"
const val spotlessPluginVersion = "6.11.0"
private const val agpVersion = "8.4.2"
private const val kotlinVersion = "2.0.0"
private const val coroutinesVersion = "1.8.1"
private const val espressoVersion = "3.6.1"
private const val roomVersion = "2.6.1"
const val detektPluginVersion = "1.23.6"
const val spotlessPluginVersion = "6.25.0"

// Gradle plugins
const val androidGradlePlugin = "com.android.tools.build:gradle:$agpVersion"
Expand All @@ -30,44 +30,44 @@ object Deps {
const val kotlinCoroutinesAndroid = "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutinesVersion"

// Android
const val appCompat = "androidx.appcompat:appcompat:1.5.1"
const val appCompat = "androidx.appcompat:appcompat:1.7.0"
const val fragmentKtx = "androidx.fragment:fragment-ktx:1.5.5"
const val roomRuntime = "androidx.room:room-runtime:$roomVersion"
const val roomCommon = "androidx.room:room-common:$roomVersion"
const val roomCompiler = "androidx.room:room-compiler:$roomVersion"
const val roomKtx = "androidx.room:room-ktx:$roomVersion"
const val activityKtx = "androidx.activity:activity-ktx:1.6.1"
const val recyclerView = "androidx.recyclerview:recyclerview:1.2.1"
const val material = "com.google.android.material:material:1.7.0"
const val activityKtx = "androidx.activity:activity-ktx:1.9.0"
const val recyclerView = "androidx.recyclerview:recyclerview:1.3.2"
const val material = "com.google.android.material:material:1.12.0"
const val lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:2.2.0"
const val documentFile = "androidx.documentfile:documentfile:1.0.1"
const val pagingRuntimeKtx = "androidx.paging:paging-runtime-ktx:3.1.1"
const val pagingRuntimeKtx = "androidx.paging:paging-runtime-ktx:3.3.0"

// Tests
const val androidJUnitRunner = "androidx.test.runner.AndroidJUnitRunner"
const val androidxTestOrchestrator = "androidx.test:orchestrator:1.4.2"
const val androidxTestOrchestrator = "androidx.test:orchestrator:1.5.0"
const val espressoCore = "androidx.test.espresso:espresso-core:$espressoVersion"
const val espressoIdlingResource = "androidx.test.espresso:espresso-idling-resource:$espressoVersion"
const val roomTesting = "androidx.room:room-testing:$roomVersion"
const val archTesting = "android.arch.core:core-testing:1.1.1"
const val archTesting = "androidx.arch.core:core-testing:2.2.0"

// Other libraries
const val detektKtlintDependency = "io.gitlab.arturbosch.detekt:detekt-formatting:$detektPluginVersion"
const val kotlinPoet = "com.squareup:kotlinpoet:1.12.0"
const val powerfulSharedPreferences = "io.github.stefanosiano.powerful_libraries:sharedpreferences:1.0.20"
const val powerfulSharedPreferencesLiveData = "io.github.stefanosiano.powerful_libraries:sharedpreferences_livedata:1.0.7"
const val powerfulSharedPreferences = "io.github.stefanosiano.powerful_libraries:sharedpreferences:1.0.21"
const val powerfulSharedPreferencesLiveData = "io.github.stefanosiano.powerful_libraries:sharedpreferences_livedata:1.0.8"

// Test libraries
private const val androidxTestVersion = "1.5.0"
private const val androidxTestVersion = "1.6.1"
const val kotlinCoroutinesTest = "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion"
const val kotlinTestJunit = "org.jetbrains.kotlin:kotlin-test-junit:$kotlinVersion"
const val robolectric = "org.robolectric:robolectric:4.7.3"
const val robolectric = "org.robolectric:robolectric:4.13"
const val androidxCore = "androidx.test:core:$androidxTestVersion"
const val androidxRunner = "androidx.test:runner:$androidxTestVersion"
const val androidxTestCoreKtx = "androidx.test:core-ktx:$androidxTestVersion"
const val androidxTestRules = "androidx.test:rules:$androidxTestVersion"
const val androidxJunit = "androidx.test.ext:junit:1.1.3"
const val androidxCoreKtx = "androidx.core:core-ktx:1.7.0"
const val androidxCoreKtx = "androidx.core:core-ktx:1.13.1"
const val mockitoKotlin = "com.nhaarman.mockitokotlin2:mockito-kotlin:2.2.0"
const val mockk = "io.mockk:mockk:1.12.5"
const val mockk = "io.mockk:mockk:1.13.11"
}
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
3 changes: 2 additions & 1 deletion powerfulsama/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
}

ext {
set("LIB_VERSION", "0.5.00") // This is the library version used when deploying the artifact
set("LIB_VERSION", "0.5.01") // This is the library version used when deploying the artifact
set("ENABLE_DEPLOY", "true") // Flag whether the ci/cd workflow should deploy to sonatype or not

set("LIB_GROUP_ID", "io.github.stefanosiano.powerful_libraries") // Maven Group ID for the artifact
Expand All @@ -19,6 +19,7 @@ ext {

android {
compileSdk = Deps.sdkCompile
namespace = "com.stefanosiano.powerful_libraries.sama"

defaultConfig {
minSdk = Deps.sdkMin
Expand Down
2 changes: 1 addition & 1 deletion powerfulsama/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<manifest package="com.stefanosiano.powerful_libraries.sama" />
<manifest />
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import androidx.lifecycle.Observer

internal class LiveDataExtensions

/**
* Transforms the liveData using the function [onValue] every time it changes, returning another liveData.
* You can optionally pass a CoroutineContext [context] to execute it in the background.
*/
/** Transforms the liveData using the function [onValue] every time it changes, returning another liveData. */
fun <T, D> LiveData<T>.transform(onValue: (t: T) -> D): LiveData<D> {
val transformedLiveData = MediatorLiveData<D>()
transformedLiveData.addSource(this) {
Expand All @@ -18,16 +15,10 @@ fun <T, D> LiveData<T>.transform(onValue: (t: T) -> D): LiveData<D> {
return transformedLiveData
}

/**
* Returns a liveData which returns values only when they change.
* You can optionally pass a CoroutineContext [context] to execute it in the background.
*/
/** Returns a liveData which returns values only when they change. */
fun <T> LiveData<T>.getDistinct(): LiveData<T> = getDistinctBy { it as Any }

/**
* Returns a liveData which returns values only when they change.
* You can optionally pass a CoroutineContext [context] to execute it in the background.
*/
/** Returns a liveData which returns values only when they change. */
fun <T> LiveData<T>.getDistinctBy(function: (T) -> Any): LiveData<T> {
val distinctLiveData = MediatorLiveData<T>()

Expand All @@ -36,28 +27,26 @@ fun <T> LiveData<T>.getDistinctBy(function: (T) -> Any): LiveData<T> {
object : Observer<T> {
private var lastObj: T? = null

override fun onChanged(obj: T?) {
if (lastObj != null && obj != null && function(lastObj!!) == function(obj)) {
override fun onChanged(value: T) {
if (lastObj != null && value != null && function(lastObj!!) == function(value)) {
return
}
lastObj = obj
distinctLiveData.postValue(lastObj)
if (value == null) {
return
}
lastObj = value
distinctLiveData.postValue(lastObj!!)
}
}
)
return distinctLiveData
}

/**
* Returns a liveData which returns values only when they change.
* You can optionally pass a CoroutineContext [context] to execute it in the background.
*/
/** Returns a liveData which returns values only when they change. */
fun <T> LiveData<List<T>>.getListDistinct(): LiveData<List<T>> = this.getListDistinctBy { it as Any }

/**
* Returns a liveData which returns values only when they change.
* You can optionally pass a CoroutineContext [context] to execute it in the background.
*/
* Returns a liveData which returns values only when they change. */
fun <T> LiveData<List<T>>.getListDistinctBy(function: (T) -> Any): LiveData<List<T>> {
val distinctLiveData = MediatorLiveData<List<T>>()

Expand All @@ -66,15 +55,15 @@ fun <T> LiveData<List<T>>.getListDistinctBy(function: (T) -> Any): LiveData<List
object : Observer<List<T>> {
private var lastObj: List<T>? = null

override fun onChanged(obj: List<T>?) {
override fun onChanged(value: List<T>) {
if (lastObj != null &&
obj?.size == lastObj?.size &&
compareListsContent(obj ?: ArrayList(), lastObj ?: ArrayList(), function)
value.size == lastObj?.size &&
compareListsContent(value, lastObj ?: ArrayList(), function)
) {
return
}
lastObj = obj
distinctLiveData.postValue(lastObj)
lastObj = value
distinctLiveData.postValue(lastObj!!)
}

private inline fun compareListsContent(list1: List<T>, list2: List<T>, compare: (T) -> Any): Boolean =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.stefanosiano.powerful_libraries.sama.ui
import android.content.Context
import android.util.AttributeSet
import android.widget.ArrayAdapter
import android.widget.AutoCompleteTextView
import androidx.appcompat.widget.SearchView
import com.stefanosiano.powerful_libraries.sama.R
import com.stefanosiano.powerful_libraries.sama.coroutineSamaHandler
Expand Down Expand Up @@ -132,7 +133,7 @@ open class SamaSearchView : SearchView, CoroutineScope {
mSuggestionsAdapter = mSuggestionsAdapter ?: ArrayAdapter(context, mSuggestionLayout)
mSuggestionsAdapter?.clear()
suggestions?.let { mSuggestionsAdapter?.addAll(it) }
val searchAutoComplete = findViewById<SearchAutoComplete>(R.id.search_src_text)
val searchAutoComplete = findViewById<AutoCompleteTextView>(R.id.search_src_text)

searchAutoComplete.setOnItemClickListener { _, _, position, _ ->
mSuggestionsAdapter?.getItem(position)?.let { logVerbose("Clicked on $it"); f(it) }
Expand All @@ -151,7 +152,7 @@ open class SamaSearchView : SearchView, CoroutineScope {
.map { mSuggestionsAdapter?.getItem(it) }
mSuggestionsAdapter = ArrayAdapter(context, mSuggestionLayout)
mSuggestionsAdapter?.addAll(oldItems)
val searchAutoComplete = findViewById<SearchAutoComplete>(R.id.search_src_text)
val searchAutoComplete = findViewById<AutoCompleteTextView>(R.id.search_src_text)
post { searchAutoComplete.setAdapter(mSuggestionsAdapter) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.lang.ref.WeakReference
import java.util.concurrent.atomic.AtomicInteger

/**
Expand Down Expand Up @@ -181,7 +182,7 @@ interface SamaObserver {
fun <T> observe(
liveData: LiveData<T>,
vararg obs: Observable,
observerFunction: (data: T) -> Unit
obFun: (data: T) -> Unit
): LiveData<T>

/**
Expand Down Expand Up @@ -370,13 +371,14 @@ class SamaObserverImpl : SamaObserver {
* Whenever [o] or any of [obs] change, [obFun] is called with the current value of [o].
* Does nothing if the value of [o] is null or already changed.
*/
@Suppress("UNCHECKED_CAST")
private fun <T> observePrivate(
o: Observable,
obFun: (data: T) -> Unit,
vararg obs: Observable
) {
val obsId = observablesId.incrementAndGet()
val helper = SamaObservableHelper(obsId, null, null)
val helper = SamaObservableHelper(obsId, null, null, obFun as (Any?) -> Unit)
synchronized(observableMap) { observableMap[obsId] = helper }

val f: () -> Unit = {
Expand All @@ -390,7 +392,7 @@ class SamaObserverImpl : SamaObserver {
}
(o.get() as? T?)?.let {
logVerbose(it.toString())
obFun(it)
helper.f?.invoke(it)
}
helper.onStart = null
}
Expand Down Expand Up @@ -427,7 +429,7 @@ class SamaObserverImpl : SamaObserver {
obFun: (data: List<T>) -> Unit
) {
val obsId = observablesId.incrementAndGet()
val helper = SamaObservableHelper(obsId, null, null)
val helper = SamaObservableHelper(obsId, null, null, obFun as (Any?) -> Unit)
synchronized(observableMap) { observableMap[obsId] = helper }

val f: () -> Unit = {
Expand All @@ -436,7 +438,7 @@ class SamaObserverImpl : SamaObserver {
if (obs.isNotEmpty()) delay(50L)
if (isPaused) return@launch
if (!isActive) return@launch
o.toList().let { logVerbose(it.toString()); obFun(it) }
o.toList().let { logVerbose(it.toString()); helper.f?.invoke(it) }
helper.onStart = null
}
}
Expand All @@ -446,18 +448,12 @@ class SamaObserverImpl : SamaObserver {
obs.map {
SamaInnerObservable(
it,
it.onPropertyChanged {
helper.onStart = f
f()
}
it.onPropertyChanged { helper.onStart = f; f() }
)
}
)

val c = o.onAnyChange {
helper.onStart = f
f()
}
val c = o.onAnyChange { helper.onStart = f; f() }
listObservables.add(
SamaInnerListObservable(
o as ObservableList<Any>,
Expand All @@ -483,7 +479,7 @@ class SamaObserverImpl : SamaObserver {
): ObservableField<R> {
val toRet = ObservableField<R>()
val obsId = observablesId.incrementAndGet()
val helper = SamaFlowHelper(obsId, null, null, null)
val helper = SamaFlowHelper(obsId, null, null, null, obFun as (Any?) -> Unit)
synchronized(flowMap) {
flowMap[obsId] = helper
}
Expand All @@ -499,7 +495,7 @@ class SamaObserverImpl : SamaObserver {
return@launch
}
logVerbose(t.toString())
toRet.set(obFun(t))
toRet.set(helper.f?.invoke(t) as R)
helper.onStart = null
}
}
Expand Down Expand Up @@ -542,13 +538,14 @@ class SamaObserverImpl : SamaObserver {
override fun <T> observe(
liveData: LiveData<T>,
vararg obs: Observable,
observerFunction: (data: T) -> Unit
obFun: (data: T) -> Unit
): LiveData<T> {
val obsId = observablesId.incrementAndGet()
val helper = SamaObservableHelper(obsId, null, null)
val helper = SamaObservableHelper(obsId, null, null, obFun as (Any?) -> Unit)
synchronized(observableMap) {
observableMap[obsId] = helper
}
val liveDataWeakRef = WeakReference(liveData)

val f: () -> Unit = {
helper.job?.cancel()
Expand All @@ -559,9 +556,9 @@ class SamaObserverImpl : SamaObserver {
if (isPaused || !isActive) {
return@launch
}
liveData.value?.let {
liveDataWeakRef.get()?.value?.let {
logVerbose(it.toString())
observerFunction(it)
helper.f?.invoke(it)
}
helper.onStart = null
}
Expand Down Expand Up @@ -679,15 +676,34 @@ class SamaObserverImpl : SamaObserver {
customObservedLiveData.clear()
}
}
synchronized(observableMap) {
observableMap.values.forEach {
it.job?.cancel()
it.job = null
it.f = null
it.onStart = null
}
observableMap.clear()
}
synchronized(flowMap) {
flowMap.values.forEach {
it.job?.cancel()
it.job = null
it.f = null
it.onStart = null
}
flowMap.clear()
}
}

private inner class SamaObservableHelper(val id: Int, var onStart: (() -> Unit)?, var job: Job?)
private inner class SamaObservableHelper(val id: Int, var onStart: (() -> Unit)?, var job: Job?, var f: ((data: Any?) -> Unit)?)

private inner class SamaFlowHelper(
val id: Int,
var onStart: ((t: Any) -> Unit)?,
var job: Job?,
var lastValue: Any?
var lastValue: Any?,
var f: ((data: Any?) -> Unit)?
)

private inner class SamaInnerFlowObservable(
Expand Down
Loading

0 comments on commit 4b07db3

Please sign in to comment.