From 75928d260d0edde098702f630414589fb49c117f Mon Sep 17 00:00:00 2001 From: kitsunyan Date: Fri, 19 Jun 2020 15:20:16 +0300 Subject: [PATCH] Refactor services --- .../kitsunyan/foxydroid/MainApplication.kt | 6 ++-- .../screen/EditRepositoryFragment.kt | 2 +- .../foxydroid/screen/ProductFragment.kt | 8 ++--- .../foxydroid/screen/RepositoriesFragment.kt | 2 +- .../foxydroid/screen/RepositoryFragment.kt | 2 +- .../foxydroid/screen/TabsFragment.kt | 2 +- .../kitsunyan/foxydroid/service/Connection.kt | 32 +++++++++---------- .../foxydroid/service/ConnectionService.kt | 19 +++++++++++ .../foxydroid/service/DownloadService.kt | 5 ++- .../foxydroid/service/SyncService.kt | 18 +++++------ .../foxydroid/utility/extension/Android.kt | 9 ------ 11 files changed, 56 insertions(+), 49 deletions(-) create mode 100644 src/main/kotlin/nya/kitsunyan/foxydroid/service/ConnectionService.kt diff --git a/src/main/kotlin/nya/kitsunyan/foxydroid/MainApplication.kt b/src/main/kotlin/nya/kitsunyan/foxydroid/MainApplication.kt index f991a87..0e4eedb 100644 --- a/src/main/kotlin/nya/kitsunyan/foxydroid/MainApplication.kt +++ b/src/main/kotlin/nya/kitsunyan/foxydroid/MainApplication.kt @@ -174,9 +174,9 @@ class MainApplication: Application() { Database.RepositoryAdapter.put(it.copy(lastModified = "", entityTag = "")) } } - Connection(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) } diff --git a/src/main/kotlin/nya/kitsunyan/foxydroid/screen/EditRepositoryFragment.kt b/src/main/kotlin/nya/kitsunyan/foxydroid/screen/EditRepositoryFragment.kt index 8056f63..5b2a08e 100644 --- a/src/main/kotlin/nya/kitsunyan/foxydroid/screen/EditRepositoryFragment.kt +++ b/src/main/kotlin/nya/kitsunyan/foxydroid/screen/EditRepositoryFragment.kt @@ -80,7 +80,7 @@ class EditRepositoryFragment(): Fragment() { private var saveMenuItem: MenuItem? = null private var layout: Layout? = null - private val syncConnection = Connection(SyncService::class.java) + private val syncConnection = Connection(SyncService::class.java) private var repositoriesDisposable: Disposable? = null private var checkDisposable: Disposable? = null diff --git a/src/main/kotlin/nya/kitsunyan/foxydroid/screen/ProductFragment.kt b/src/main/kotlin/nya/kitsunyan/foxydroid/screen/ProductFragment.kt index dca2774..2dbf6a3 100644 --- a/src/main/kotlin/nya/kitsunyan/foxydroid/screen/ProductFragment.kt +++ b/src/main/kotlin/nya/kitsunyan/foxydroid/screen/ProductFragment.kt @@ -72,10 +72,10 @@ class ProductFragment(): Fragment(), ProductAdapter.Callbacks { private var productDisposable: Disposable? = null private var downloadDisposable: Disposable? = null - private val downloadConnection = Connection(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 }) diff --git a/src/main/kotlin/nya/kitsunyan/foxydroid/screen/RepositoriesFragment.kt b/src/main/kotlin/nya/kitsunyan/foxydroid/screen/RepositoriesFragment.kt index 7ae358c..8c72597 100644 --- a/src/main/kotlin/nya/kitsunyan/foxydroid/screen/RepositoriesFragment.kt +++ b/src/main/kotlin/nya/kitsunyan/foxydroid/screen/RepositoriesFragment.kt @@ -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::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 { diff --git a/src/main/kotlin/nya/kitsunyan/foxydroid/screen/RepositoryFragment.kt b/src/main/kotlin/nya/kitsunyan/foxydroid/screen/RepositoryFragment.kt index c05d2b7..104fc9e 100644 --- a/src/main/kotlin/nya/kitsunyan/foxydroid/screen/RepositoryFragment.kt +++ b/src/main/kotlin/nya/kitsunyan/foxydroid/screen/RepositoryFragment.kt @@ -43,7 +43,7 @@ class RepositoryFragment(): Fragment() { private var layout: LinearLayout? = null - private val syncConnection = Connection(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 { diff --git a/src/main/kotlin/nya/kitsunyan/foxydroid/screen/TabsFragment.kt b/src/main/kotlin/nya/kitsunyan/foxydroid/screen/TabsFragment.kt index 6586dd9..355f009 100644 --- a/src/main/kotlin/nya/kitsunyan/foxydroid/screen/TabsFragment.kt +++ b/src/main/kotlin/nya/kitsunyan/foxydroid/screen/TabsFragment.kt @@ -80,7 +80,7 @@ class TabsFragment: Fragment() { private var category = "" private var order = ProductItem.Order.NAME - private val syncConnection = Connection(SyncService::class.java, onBind = { + private val syncConnection = Connection(SyncService::class.java, onBind = { _, _ -> viewPager?.let { val source = ProductsFragment.Source.values()[it.currentItem] updateUpdateNotificationBlocker(source) diff --git a/src/main/kotlin/nya/kitsunyan/foxydroid/service/Connection.kt b/src/main/kotlin/nya/kitsunyan/foxydroid/service/Connection.kt index 0cceabd..749be63 100644 --- a/src/main/kotlin/nya/kitsunyan/foxydroid/service/Connection.kt +++ b/src/main/kotlin/nya/kitsunyan/foxydroid/service/Connection.kt @@ -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(private val serviceClass: Class, - private val onBind: ((Event) -> Unit)? = null, - private val onUnbind: ((Event) -> Unit)? = null): ServiceConnection { - class Event(val connection: Connection, val binder: T) - - var binder: T? = null +class Connection>(private val serviceClass: Class, + private val onBind: ((Connection, B) -> Unit)? = null, + private val onUnbind: ((Connection, 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(private val serviceClass: Class, fun unbind(context: Context) { context.unbindService(this) - binder?.let { - binder = null - onUnbind?.invoke(Event(this, it)) - } + handleUnbind() } } diff --git a/src/main/kotlin/nya/kitsunyan/foxydroid/service/ConnectionService.kt b/src/main/kotlin/nya/kitsunyan/foxydroid/service/ConnectionService.kt new file mode 100644 index 0000000..f3b35a3 --- /dev/null +++ b/src/main/kotlin/nya/kitsunyan/foxydroid/service/ConnectionService.kt @@ -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: 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) + } + } +} diff --git a/src/main/kotlin/nya/kitsunyan/foxydroid/service/DownloadService.kt b/src/main/kotlin/nya/kitsunyan/foxydroid/service/DownloadService.kt index be0c26c..a4fdfeb 100644 --- a/src/main/kotlin/nya/kitsunyan/foxydroid/service/DownloadService.kt +++ b/src/main/kotlin/nya/kitsunyan/foxydroid/service/DownloadService.kt @@ -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() { 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()) diff --git a/src/main/kotlin/nya/kitsunyan/foxydroid/service/SyncService.kt b/src/main/kotlin/nya/kitsunyan/foxydroid/service/SyncService.kt index cbadf20..8f01391 100644 --- a/src/main/kotlin/nya/kitsunyan/foxydroid/service/SyncService.kt +++ b/src/main/kotlin/nya/kitsunyan/foxydroid/service/SyncService.kt @@ -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() { 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(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 diff --git a/src/main/kotlin/nya/kitsunyan/foxydroid/utility/extension/Android.kt b/src/main/kotlin/nya/kitsunyan/foxydroid/utility/extension/Android.kt index beb68af..5b5cb6c 100644 --- a/src/main/kotlin/nya/kitsunyan/foxydroid/utility/extension/Android.kt +++ b/src/main/kotlin/nya/kitsunyan/foxydroid/utility/extension/Android.kt @@ -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()