SyncThread: Fix issue when network is back and the app was in background: do not restart the thread
This commit is contained in:
parent
73ec0f5a83
commit
25e9a179d2
|
@ -36,7 +36,8 @@ internal class NetworkConnectivityChecker @Inject constructor(context: Context)
|
|||
private val listeners = Collections.synchronizedSet(LinkedHashSet<Listener>())
|
||||
|
||||
// True when internet is available
|
||||
private var hasInternetAccess = false
|
||||
var hasInternetAccess = false
|
||||
private set
|
||||
|
||||
init {
|
||||
merlin.bind()
|
||||
|
@ -63,7 +64,7 @@ internal class NetworkConnectivityChecker @Inject constructor(context: Context)
|
|||
}
|
||||
|
||||
suspend fun waitUntilConnected() {
|
||||
if (isConnected()) {
|
||||
if (hasInternetAccess) {
|
||||
return
|
||||
} else {
|
||||
suspendCoroutine<Unit> { continuation ->
|
||||
|
@ -85,10 +86,6 @@ internal class NetworkConnectivityChecker @Inject constructor(context: Context)
|
|||
listeners.remove(listener)
|
||||
}
|
||||
|
||||
fun isConnected(): Boolean {
|
||||
return hasInternetAccess
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
fun onConnect() {
|
||||
|
||||
|
|
|
@ -93,8 +93,8 @@ open class SyncService : Service() {
|
|||
}
|
||||
|
||||
fun doSync(once: Boolean = false) {
|
||||
if (!networkConnectivityChecker.isConnected()) {
|
||||
Timber.v("Sync is Paused. Waiting...")
|
||||
if (!networkConnectivityChecker.hasInternetAccess) {
|
||||
Timber.v("No internet access. Waiting...")
|
||||
//TODO Retry in ?
|
||||
timer.schedule(object : TimerTask() {
|
||||
override fun run() {
|
||||
|
|
|
@ -50,6 +50,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
|
|||
private val lock = Object()
|
||||
private var cancelableTask: Cancelable? = null
|
||||
|
||||
private var isStarted = false
|
||||
|
||||
init {
|
||||
updateStateTo(SyncState.IDLE)
|
||||
}
|
||||
|
@ -60,19 +62,18 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
|
|||
}
|
||||
|
||||
fun restart() = synchronized(lock) {
|
||||
if (state is SyncState.PAUSED) {
|
||||
if (!isStarted) {
|
||||
Timber.v("Resume sync...")
|
||||
updateStateTo(SyncState.RUNNING(afterPause = true))
|
||||
isStarted = true
|
||||
lock.notify()
|
||||
}
|
||||
}
|
||||
|
||||
fun pause() = synchronized(lock) {
|
||||
if (state is SyncState.RUNNING) {
|
||||
if (isStarted) {
|
||||
Timber.v("Pause sync...")
|
||||
updateStateTo(SyncState.PAUSED)
|
||||
isStarted = false
|
||||
cancelableTask?.cancel()
|
||||
lock.notify()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,21 +88,31 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
|
|||
return liveState
|
||||
}
|
||||
|
||||
override fun onConnect() {
|
||||
Timber.v("Network is back")
|
||||
synchronized(lock) {
|
||||
lock.notify()
|
||||
}
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
Timber.v("Start syncing...")
|
||||
isStarted = true
|
||||
networkConnectivityChecker.register(this)
|
||||
backgroundDetectionObserver.register(this)
|
||||
|
||||
while (state != SyncState.KILLING) {
|
||||
Timber.v("Entering loop, state: $state")
|
||||
|
||||
if (!networkConnectivityChecker.isConnected() || state == SyncState.PAUSED) {
|
||||
Timber.v("No network or sync is Paused. Waiting...")
|
||||
if (!networkConnectivityChecker.hasInternetAccess) {
|
||||
Timber.v("No network. Waiting...")
|
||||
updateStateTo(SyncState.NO_NETWORK)
|
||||
|
||||
synchronized(lock) {
|
||||
lock.wait()
|
||||
}
|
||||
synchronized(lock) { lock.wait() }
|
||||
Timber.v("...unlocked")
|
||||
} else if (!isStarted) {
|
||||
Timber.v("Sync is Paused. Waiting...")
|
||||
updateStateTo(SyncState.PAUSED)
|
||||
synchronized(lock) { lock.wait() }
|
||||
Timber.v("...unlocked")
|
||||
} else {
|
||||
if (state !is SyncState.RUNNING) {
|
||||
|
@ -169,16 +180,11 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
|
|||
}
|
||||
|
||||
private fun updateStateTo(newState: SyncState) {
|
||||
Timber.v("Update state to $newState")
|
||||
Timber.v("Update state from $state to $newState")
|
||||
state = newState
|
||||
liveState.postValue(newState)
|
||||
}
|
||||
|
||||
override fun onConnect() {
|
||||
synchronized(lock) {
|
||||
lock.notify()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMoveToForeground() {
|
||||
restart()
|
||||
|
|
|
@ -33,7 +33,7 @@ internal class BackgroundDetectionObserver @Inject constructor() : LifecycleObse
|
|||
private set
|
||||
|
||||
private
|
||||
val listeners = ArrayList<Listener>()
|
||||
val listeners = LinkedHashSet<Listener>()
|
||||
|
||||
fun register(listener: Listener) {
|
||||
listeners.add(listener)
|
||||
|
|
|
@ -38,6 +38,6 @@ class SyncStateView @JvmOverloads constructor(context: Context, attrs: Attribute
|
|||
is SyncState.RUNNING -> if (newState.afterPause) View.VISIBLE else View.GONE
|
||||
else -> View.GONE
|
||||
}
|
||||
syncStateNoNetwork.isVisible = newState is SyncState.NO_NETWORK
|
||||
syncStateNoNetwork.isVisible = newState == SyncState.NO_NETWORK
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue