Refactor services

This commit is contained in:
kitsunyan
2020-06-19 15:20:16 +03:00
parent 561352b685
commit 75928d260d
11 changed files with 56 additions and 49 deletions
@@ -174,9 +174,9 @@ class MainApplication: Application() {
Database.RepositoryAdapter.put(it.copy(lastModified = "", entityTag = ""))
}
}
Connection<SyncService.Binder>(SyncService::class.java, onBind = {
it.binder.sync(SyncService.SyncRequest.FORCE)
it.connection.unbind(this)
Connection(SyncService::class.java, onBind = { connection, binder ->
binder.sync(SyncService.SyncRequest.FORCE)
connection.unbind(this)
}).bind(this)
}
@@ -80,7 +80,7 @@ class EditRepositoryFragment(): Fragment() {
private var saveMenuItem: MenuItem? = null
private var layout: Layout? = null
private val syncConnection = Connection<SyncService.Binder>(SyncService::class.java)
private val syncConnection = Connection(SyncService::class.java)
private var repositoriesDisposable: Disposable? = null
private var checkDisposable: Disposable? = null
@@ -72,10 +72,10 @@ class ProductFragment(): Fragment(), ProductAdapter.Callbacks {
private var productDisposable: Disposable? = null
private var downloadDisposable: Disposable? = null
private val downloadConnection = Connection<DownloadService.Binder>(DownloadService::class.java, onBind = {
updateDownloadState(it.binder.getState(packageName))
downloadDisposable = it.binder.events(packageName).subscribe { updateDownloadState(it) }
}, onUnbind = {
private val downloadConnection = Connection(DownloadService::class.java, onBind = { _, binder ->
updateDownloadState(binder.getState(packageName))
downloadDisposable = binder.events(packageName).subscribe { updateDownloadState(it) }
}, onUnbind = { _, _ ->
downloadDisposable?.dispose()
downloadDisposable = null
})
@@ -20,7 +20,7 @@ import nya.kitsunyan.foxydroid.utility.Utils
class RepositoriesFragment: Fragment(), CursorOwner.Callback {
private var recyclerView: RecyclerView? = null
private val syncConnection = Connection<SyncService.Binder>(SyncService::class.java)
private val syncConnection = Connection(SyncService::class.java)
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment, container, false).apply {
@@ -43,7 +43,7 @@ class RepositoryFragment(): Fragment() {
private var layout: LinearLayout? = null
private val syncConnection = Connection<SyncService.Binder>(SyncService::class.java)
private val syncConnection = Connection(SyncService::class.java)
private var repositoryDisposable: Disposable? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
@@ -80,7 +80,7 @@ class TabsFragment: Fragment() {
private var category = ""
private var order = ProductItem.Order.NAME
private val syncConnection = Connection<SyncService.Binder>(SyncService::class.java, onBind = {
private val syncConnection = Connection(SyncService::class.java, onBind = { _, _ ->
viewPager?.let {
val source = ProductsFragment.Source.values()[it.currentItem]
updateUpdateNotificationBlocker(source)
@@ -1,32 +1,33 @@
package nya.kitsunyan.foxydroid.service
import android.app.Service
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.IBinder
class Connection<T: IBinder>(private val serviceClass: Class<out Service>,
private val onBind: ((Event<T>) -> Unit)? = null,
private val onUnbind: ((Event<T>) -> Unit)? = null): ServiceConnection {
class Event<T: IBinder>(val connection: Connection<T>, val binder: T)
var binder: T? = null
class Connection<B: IBinder, S: ConnectionService<B>>(private val serviceClass: Class<S>,
private val onBind: ((Connection<B, S>, B) -> Unit)? = null,
private val onUnbind: ((Connection<B, S>, B) -> Unit)? = null): ServiceConnection {
var binder: B? = null
private set
private fun handleUnbind() {
binder?.let {
binder = null
onUnbind?.invoke(this, it)
}
}
override fun onServiceConnected(componentName: ComponentName, binder: IBinder) {
@Suppress("UNCHECKED_CAST")
binder as T
binder as B
this.binder = binder
onBind?.invoke(Event(this, binder))
onBind?.invoke(this, binder)
}
override fun onServiceDisconnected(componentName: ComponentName) {
binder?.let {
binder = null
onUnbind?.invoke(Event(this, it))
}
handleUnbind()
}
fun bind(context: Context) {
@@ -35,9 +36,6 @@ class Connection<T: IBinder>(private val serviceClass: Class<out Service>,
fun unbind(context: Context) {
context.unbindService(this)
binder?.let {
binder = null
onUnbind?.invoke(Event(this, it))
}
handleUnbind()
}
}
@@ -0,0 +1,19 @@
package nya.kitsunyan.foxydroid.service
import android.app.Service
import android.content.Intent
import android.os.IBinder
import nya.kitsunyan.foxydroid.utility.extension.android.Android
abstract class ConnectionService<T: IBinder>: Service() {
abstract override fun onBind(intent: Intent): T
fun startSelf() {
val intent = Intent(this, this::class.java)
if (Android.sdk(26)) {
startForegroundService(intent)
} else {
startService(intent)
}
}
}
@@ -3,7 +3,6 @@ package nya.kitsunyan.foxydroid.service
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
@@ -31,7 +30,7 @@ import java.security.MessageDigest
import java.util.concurrent.TimeUnit
import kotlin.math.*
class DownloadService: Service() {
class DownloadService: ConnectionService<DownloadService.Binder>() {
companion object {
private const val ACTION_OPEN = "${BuildConfig.APPLICATION_ID}.intent.action.OPEN"
private const val ACTION_INSTALL = "${BuildConfig.APPLICATION_ID}.intent.action.INSTALL"
@@ -326,7 +325,7 @@ class DownloadService: Service() {
val task = tasks.removeAt(0)
if (!started) {
started = true
startAnyService(Intent(this, this::class.java))
startSelf()
}
val initialState = State.Connecting(task.packageName, task.name)
stateNotificationBuilder.setWhen(System.currentTimeMillis())
@@ -3,7 +3,6 @@ package nya.kitsunyan.foxydroid.service
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.app.job.JobParameters
import android.app.job.JobService
import android.content.Intent
@@ -35,7 +34,7 @@ import java.lang.ref.WeakReference
import java.util.concurrent.TimeUnit
import kotlin.math.*
class SyncService: Service() {
class SyncService: ConnectionService<SyncService.Binder>() {
companion object {
private const val ACTION_CANCEL = "${BuildConfig.APPLICATION_ID}.intent.action.CANCEL"
@@ -77,6 +76,7 @@ class SyncService: Service() {
handleNextTask(cancelledTask?.hasUpdates == true)
if (request != SyncRequest.AUTO && started == Started.AUTO) {
started = Started.MANUAL
startSelf()
handleSetStarted()
currentTask?.lastState?.let { publishForegroundState(true, it) }
}
@@ -273,7 +273,6 @@ class SyncService: Service() {
}
private fun handleSetStarted() {
startAnyService(Intent(this, this::class.java))
stateNotificationBuilder.setWhen(System.currentTimeMillis())
}
@@ -287,6 +286,7 @@ class SyncService: Service() {
val newStarted = if (task.manual || lastStarted == Started.MANUAL) Started.MANUAL else Started.AUTO
started = newStarted
if (newStarted == Started.MANUAL && lastStarted != Started.MANUAL) {
startSelf()
handleSetStarted()
}
val initialState = State.Connecting(repository.name)
@@ -379,22 +379,22 @@ class SyncService: Service() {
class Job: JobService() {
private var syncParams: JobParameters? = null
private var syncDisposable: Disposable? = null
private val syncConnection = Connection<Binder>(SyncService::class.java, onBind = {
syncDisposable = it.binder.finish.subscribe { _ ->
private val syncConnection = Connection(SyncService::class.java, onBind = { connection, binder ->
syncDisposable = binder.finish.subscribe {
val params = syncParams
if (params != null) {
syncParams = null
syncDisposable?.dispose()
syncDisposable = null
it.connection.unbind(this)
connection.unbind(this)
jobFinished(params, false)
}
}
it.binder.sync(SyncRequest.AUTO)
}, onUnbind = {
binder.sync(SyncRequest.AUTO)
}, onUnbind = { _, binder ->
syncDisposable?.dispose()
syncDisposable = null
it.binder.cancelAuto()
binder.cancelAuto()
val params = syncParams
if (params != null) {
syncParams = null
@@ -3,7 +3,6 @@ package nya.kitsunyan.foxydroid.utility.extension.android
import android.app.NotificationManager
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.Signature
import android.database.Cursor
@@ -25,14 +24,6 @@ fun SQLiteDatabase.execWithResult(sql: String) {
val Context.notificationManager: NotificationManager
get() = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
fun Context.startAnyService(intent: Intent) {
if (Android.sdk(26)) {
startForegroundService(intent)
} else {
startService(intent)
}
}
val PackageInfo.versionCodeCompat: Long
get() = if (Android.sdk(28)) longVersionCode else @Suppress("DEPRECATION") versionCode.toLong()