mirror of
https://github.com/Aviortheking/Neo-Store.git
synced 2025-04-24 03:42:15 +00:00
Improve: Use IO Thread to show notification (Inconsistent Notification)
Improve: List Animation Disabled by default Add: Coroutine and Lifecycle Dependencies
This commit is contained in:
parent
06f6d2b56c
commit
bc44c9de15
14
build.gradle
14
build.gradle
@ -129,12 +129,16 @@ dependencies {
|
|||||||
// Backend
|
// Backend
|
||||||
implementation 'io.coil-kt:coil:1.4.0'
|
implementation 'io.coil-kt:coil:1.4.0'
|
||||||
implementation 'androidx.core:core-ktx:1.7.0'
|
implementation 'androidx.core:core-ktx:1.7.0'
|
||||||
implementation 'io.reactivex.rxjava3:rxjava:3.1.1'
|
|
||||||
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
|
|
||||||
implementation 'com.fasterxml.jackson.core:jackson-core:2.13.0'
|
|
||||||
implementation 'com.squareup.okhttp3:okhttp:4.9.2'
|
|
||||||
implementation 'com.github.topjohnwu.libsu:core:3.1.2'
|
|
||||||
implementation 'androidx.room:room-runtime:2.3.0'
|
implementation 'androidx.room:room-runtime:2.3.0'
|
||||||
|
implementation 'io.reactivex.rxjava3:rxjava:3.1.1'
|
||||||
|
implementation 'com.squareup.okhttp3:okhttp:4.9.2'
|
||||||
|
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
|
||||||
|
implementation 'com.github.topjohnwu.libsu:core:3.1.2'
|
||||||
|
implementation 'com.fasterxml.jackson.core:jackson-core:2.13.0'
|
||||||
|
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.4.0'
|
||||||
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
|
||||||
|
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'
|
||||||
|
|
||||||
implementation 'androidx.room:room-ktx:2.3.0'
|
implementation 'androidx.room:room-ktx:2.3.0'
|
||||||
kapt 'androidx.room:room-compiler:2.3.0'
|
kapt 'androidx.room:room-compiler:2.3.0'
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ object Preferences {
|
|||||||
Key<Boolean>("incompatible_versions", Value.BooleanValue(false))
|
Key<Boolean>("incompatible_versions", Value.BooleanValue(false))
|
||||||
|
|
||||||
object ListAnimation :
|
object ListAnimation :
|
||||||
Key<Boolean>("list_animation", Value.BooleanValue(true))
|
Key<Boolean>("list_animation", Value.BooleanValue(false))
|
||||||
|
|
||||||
object ProxyHost : Key<String>("proxy_host", Value.StringValue("localhost"))
|
object ProxyHost : Key<String>("proxy_host", Value.StringValue("localhost"))
|
||||||
object ProxyPort : Key<Int>("proxy_port", Value.IntValue(9050))
|
object ProxyPort : Key<Int>("proxy_port", Value.IntValue(9050))
|
||||||
|
@ -29,27 +29,34 @@ import com.looker.droidify.utility.extension.android.notificationManager
|
|||||||
import com.looker.droidify.utility.extension.resources.getColorFromAttr
|
import com.looker.droidify.utility.extension.resources.getColorFromAttr
|
||||||
import com.looker.droidify.utility.extension.text.formatSize
|
import com.looker.droidify.utility.extension.text.formatSize
|
||||||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.rxjava3.core.Observable
|
|
||||||
import io.reactivex.rxjava3.disposables.Disposable
|
import io.reactivex.rxjava3.disposables.Disposable
|
||||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
import io.reactivex.rxjava3.schedulers.Schedulers.io
|
||||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
import kotlinx.coroutines.*
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.SharedFlow
|
||||||
|
import kotlinx.coroutines.flow.asSharedFlow
|
||||||
|
import kotlinx.coroutines.flow.collect
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import java.util.concurrent.TimeUnit
|
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class SyncService : ConnectionService<SyncService.Binder>() {
|
class SyncService : ConnectionService<SyncService.Binder>() {
|
||||||
|
private val scope = CoroutineScope(Dispatchers.Default)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ACTION_CANCEL = "${BuildConfig.APPLICATION_ID}.intent.action.CANCEL"
|
private const val ACTION_CANCEL = "${BuildConfig.APPLICATION_ID}.intent.action.CANCEL"
|
||||||
|
|
||||||
private val stateSubject = PublishSubject.create<State>()
|
private val mutableStateSubject = MutableSharedFlow<State>()
|
||||||
private val finishSubject = PublishSubject.create<Unit>()
|
private val mutableFinishSubject = MutableSharedFlow<Unit>()
|
||||||
|
|
||||||
|
private val stateSubject = mutableStateSubject.asSharedFlow()
|
||||||
|
private val finishSubject = mutableFinishSubject.asSharedFlow()
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class State {
|
private sealed class State {
|
||||||
data class Connecting(val name: String) : State()
|
data class Connecting(val name: String) : State()
|
||||||
data class Syncing(
|
data class Syncing(
|
||||||
val name: String, val stage: RepositoryUpdater.Stage,
|
val name: String, val stage: RepositoryUpdater.Stage,
|
||||||
val read: Long, val total: Long?
|
val read: Long, val total: Long?,
|
||||||
) : State()
|
) : State()
|
||||||
|
|
||||||
object Finishing : State()
|
object Finishing : State()
|
||||||
@ -58,7 +65,7 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
private class Task(val repositoryId: Long, val manual: Boolean)
|
private class Task(val repositoryId: Long, val manual: Boolean)
|
||||||
private data class CurrentTask(
|
private data class CurrentTask(
|
||||||
val task: Task?, val disposable: Disposable,
|
val task: Task?, val disposable: Disposable,
|
||||||
val hasUpdates: Boolean, val lastState: State
|
val hasUpdates: Boolean, val lastState: State,
|
||||||
)
|
)
|
||||||
|
|
||||||
private enum class Started { NO, AUTO, MANUAL }
|
private enum class Started { NO, AUTO, MANUAL }
|
||||||
@ -72,7 +79,7 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
enum class SyncRequest { AUTO, MANUAL, FORCE }
|
enum class SyncRequest { AUTO, MANUAL, FORCE }
|
||||||
|
|
||||||
inner class Binder : android.os.Binder() {
|
inner class Binder : android.os.Binder() {
|
||||||
val finish: Observable<Unit>
|
val finish: SharedFlow<Unit>
|
||||||
get() = finishSubject
|
get() = finishSubject
|
||||||
|
|
||||||
private fun sync(ids: List<Long>, request: SyncRequest) {
|
private fun sync(ids: List<Long>, request: SyncRequest) {
|
||||||
@ -152,8 +159,6 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
private val binder = Binder()
|
private val binder = Binder()
|
||||||
override fun onBind(intent: Intent): Binder = binder
|
override fun onBind(intent: Intent): Binder = binder
|
||||||
|
|
||||||
private var stateDisposable: Disposable? = null
|
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
|
||||||
@ -170,17 +175,17 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
)
|
)
|
||||||
.let(notificationManager::createNotificationChannel)
|
.let(notificationManager::createNotificationChannel)
|
||||||
}
|
}
|
||||||
|
scope.launch(Dispatchers.Default) {
|
||||||
stateDisposable = stateSubject
|
stateSubject.collect {
|
||||||
.sample(500L, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread())
|
publishForegroundState(false,
|
||||||
.subscribe { publishForegroundState(false, it) }
|
it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
scope.cancel()
|
||||||
stateDisposable?.dispose()
|
|
||||||
stateDisposable = null
|
|
||||||
cancelTasks { true }
|
cancelTasks { true }
|
||||||
cancelCurrentTask { true }
|
cancelCurrentTask { true }
|
||||||
}
|
}
|
||||||
@ -349,8 +354,9 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
lateinit var disposable: Disposable
|
lateinit var disposable: Disposable
|
||||||
disposable = RepositoryUpdater
|
disposable = RepositoryUpdater
|
||||||
.update(this, repository, unstable) { stage, progress, total ->
|
.update(this, repository, unstable) { stage, progress, total ->
|
||||||
|
scope.launch(Dispatchers.Default) {
|
||||||
if (!disposable.isDisposed) {
|
if (!disposable.isDisposed) {
|
||||||
stateSubject.onNext(
|
mutableStateSubject.emit(
|
||||||
State.Syncing(
|
State.Syncing(
|
||||||
repository.name,
|
repository.name,
|
||||||
stage,
|
stage,
|
||||||
@ -360,7 +366,8 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
}
|
||||||
|
.observeOn(io())
|
||||||
.subscribe { result, throwable ->
|
.subscribe { result, throwable ->
|
||||||
currentTask = null
|
currentTask = null
|
||||||
throwable?.printStackTrace()
|
throwable?.printStackTrace()
|
||||||
@ -391,7 +398,7 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
.toList()
|
.toList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe { result, throwable ->
|
.subscribe { result, throwable ->
|
||||||
throwable?.printStackTrace()
|
throwable?.printStackTrace()
|
||||||
@ -404,7 +411,7 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
}
|
}
|
||||||
currentTask = CurrentTask(null, disposable, true, State.Finishing)
|
currentTask = CurrentTask(null, disposable, true, State.Finishing)
|
||||||
} else {
|
} else {
|
||||||
finishSubject.onNext(Unit)
|
scope.launch(Dispatchers.Main) { mutableFinishSubject.emit(Unit) }
|
||||||
val needStop = started == Started.MANUAL
|
val needStop = started == Started.MANUAL
|
||||||
started = Started.NO
|
started = Started.NO
|
||||||
if (needStop) {
|
if (needStop) {
|
||||||
@ -472,23 +479,20 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
|
|
||||||
class Job : JobService() {
|
class Job : JobService() {
|
||||||
private var syncParams: JobParameters? = null
|
private var syncParams: JobParameters? = null
|
||||||
private var syncDisposable: Disposable? = null
|
|
||||||
private val syncConnection =
|
private val syncConnection =
|
||||||
Connection(SyncService::class.java, onBind = { connection, binder ->
|
Connection(SyncService::class.java, onBind = { connection, binder ->
|
||||||
syncDisposable = binder.finish.subscribe {
|
MainScope().launch {
|
||||||
|
binder.finish.collect {
|
||||||
val params = syncParams
|
val params = syncParams
|
||||||
if (params != null) {
|
if (params != null) {
|
||||||
syncParams = null
|
syncParams = null
|
||||||
syncDisposable?.dispose()
|
connection.unbind(this@Job)
|
||||||
syncDisposable = null
|
|
||||||
connection.unbind(this)
|
|
||||||
jobFinished(params, false)
|
jobFinished(params, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binder.sync(SyncRequest.AUTO)
|
binder.sync(SyncRequest.AUTO)
|
||||||
|
}
|
||||||
}, onUnbind = { _, binder ->
|
}, onUnbind = { _, binder ->
|
||||||
syncDisposable?.dispose()
|
|
||||||
syncDisposable = null
|
|
||||||
binder.cancelAuto()
|
binder.cancelAuto()
|
||||||
val params = syncParams
|
val params = syncParams
|
||||||
if (params != null) {
|
if (params != null) {
|
||||||
@ -505,8 +509,6 @@ class SyncService : ConnectionService<SyncService.Binder>() {
|
|||||||
|
|
||||||
override fun onStopJob(params: JobParameters): Boolean {
|
override fun onStopJob(params: JobParameters): Boolean {
|
||||||
syncParams = null
|
syncParams = null
|
||||||
syncDisposable?.dispose()
|
|
||||||
syncDisposable = null
|
|
||||||
val reschedule = syncConnection.binder?.cancelAuto() == true
|
val reschedule = syncConnection.binder?.cancelAuto() == true
|
||||||
syncConnection.unbind(this)
|
syncConnection.unbind(this)
|
||||||
return reschedule
|
return reschedule
|
||||||
|
Loading…
x
Reference in New Issue
Block a user