AddFeed: use WorkerManager instead of the custom JobIntentService
authorDa Risk <da_risk@geekorum.com>
Fri, 14 Jun 2019 14:20:41 -0700
changeset 251 ac20fbd55433
parent 250 447cbf62117f
child 252 181ecfc58fa5
AddFeed: use WorkerManager instead of the custom JobIntentService
app/build.gradle.kts
app/src/main/AndroidManifest.xml
app/src/main/java/com/geekorum/ttrss/BackgroundJobManager.kt
app/src/main/java/com/geekorum/ttrss/add_feed/AddFeedWorker.kt
app/src/main/java/com/geekorum/ttrss/add_feed/di.kt
--- a/app/build.gradle.kts	Thu Jun 13 16:44:01 2019 -0700
+++ b/app/build.gradle.kts	Fri Jun 14 14:20:41 2019 -0700
@@ -185,6 +185,8 @@
     androidTestImplementation("androidx.room:room-testing:$roomVersion")
     dualTestImplementation("androidx.test.ext:truth:1.1.0")
 
+    implementation("androidx.work:work-runtime-ktx:2.1.0-beta01")
+
     val kotlinVersion: String by rootProject.extra
     implementation(enforcedPlatform(kotlin("bom", kotlinVersion)))
     implementation(kotlin("stdlib-jdk8"))
--- a/app/src/main/AndroidManifest.xml	Thu Jun 13 16:44:01 2019 -0700
+++ b/app/src/main/AndroidManifest.xml	Fri Jun 14 14:20:41 2019 -0700
@@ -133,6 +133,10 @@
             android:name="com.geekorum.ttrss.providers.ArticlesProvider"
             android:exported="false"/>
 
+        <!-- Disable WorkManagerInitializer and initialize manually in Application -->
+        <provider android:name="androidx.work.impl.WorkManagerInitializer"
+                android:enabled="false"/>
+
     </application>
 
 </manifest>
--- a/app/src/main/java/com/geekorum/ttrss/BackgroundJobManager.kt	Thu Jun 13 16:44:01 2019 -0700
+++ b/app/src/main/java/com/geekorum/ttrss/BackgroundJobManager.kt	Fri Jun 14 14:20:41 2019 -0700
@@ -32,9 +32,16 @@
 import android.os.Bundle
 import androidx.annotation.RequiresApi
 import androidx.core.content.getSystemService
+import androidx.work.Configuration
+import androidx.work.Constraints
+import androidx.work.NetworkType
+import androidx.work.OneTimeWorkRequestBuilder
+import androidx.work.WorkManager
 import com.geekorum.geekdroid.dagger.AppInitializer
 import com.geekorum.geekdroid.dagger.AppInitializersModule
-import com.geekorum.ttrss.add_feed.AddFeedService
+import com.geekorum.geekdroid.dagger.DaggerDelegateWorkersFactory
+import com.geekorum.geekdroid.dagger.WorkerInjectionModule
+import com.geekorum.ttrss.add_feed.AddFeedWorker
 import com.geekorum.ttrss.providers.ArticlesContract
 import com.geekorum.ttrss.providers.PurgeArticlesJobService
 import com.geekorum.ttrss.sync.SyncContract
@@ -151,8 +158,15 @@
         account: Account, feedUrl: String,
         categoryId: Long, feedLogin: String, feedPassword: String
     ) {
-        AddFeedService.subscribeToFeed(BackgroundJobManager.SUBSCRIBE_TO_FEED_JOB_ID, context, account, feedUrl, categoryId, feedLogin,
-            feedPassword)
+        val inputData = AddFeedWorker.getInputData(account, feedUrl, categoryId, feedLogin, feedPassword)
+        val workRequest = OneTimeWorkRequestBuilder<AddFeedWorker>()
+            .setConstraints(Constraints.Builder()
+                .setRequiredNetworkType(NetworkType.CONNECTED)
+                .build())
+            .setInputData(inputData)
+            .build()
+        WorkManager.getInstance(context).enqueue(workRequest)
+
     }
 
 }
@@ -160,15 +174,21 @@
 
 
 class BackgrounJobManagerInitializer @Inject constructor(
-    private val backgroundJobManager: BackgroundJobManager
+    private val backgroundJobManager: BackgroundJobManager,
+    private val workerFactory: DaggerDelegateWorkersFactory
 ) : AppInitializer {
 
     override fun initialize(app: Application) {
         backgroundJobManager.setupPeriodicJobs()
+
+        val config = Configuration.Builder()
+            .setWorkerFactory(workerFactory)
+            .build()
+        WorkManager.initialize(app, config)
     }
 }
 
-@Module(includes = [AppInitializersModule::class])
+@Module(includes = [AppInitializersModule::class, WorkerInjectionModule::class])
 abstract class BackgroundJobsModule {
 
     @Binds
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/main/java/com/geekorum/ttrss/add_feed/AddFeedWorker.kt	Fri Jun 14 14:20:41 2019 -0700
@@ -0,0 +1,96 @@
+/*
+ * Geekttrss is a RSS feed reader application on the Android Platform.
+ *
+ * Copyright (C) 2017-2019 by Frederic-Charles Barthelery.
+ *
+ * This file is part of Geekttrss.
+ *
+ * Geekttrss is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Geekttrss is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Geekttrss.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package com.geekorum.ttrss.add_feed
+
+import android.accounts.Account
+import android.content.Context
+import androidx.work.CoroutineWorker
+import androidx.work.Data
+import androidx.work.ListenableWorker
+import androidx.work.WorkerFactory
+import androidx.work.WorkerParameters
+import androidx.work.workDataOf
+import timber.log.Timber
+import javax.inject.Inject
+
+class AddFeedWorker(
+    contex: Context,
+    params: WorkerParameters,
+    private val addFeedJobFactory: AddFeedJob.Factory
+) : CoroutineWorker(contex, params) {
+    override suspend fun doWork(): Result {
+        val addFeedJob = createAddFeedJob(inputData)
+        if (!addFeedJob.addFeed()) {
+            Timber.e("Unable to add feed")
+            return Result.failure()
+        }
+        return Result.success()
+    }
+
+    private fun createAddFeedJob(inputData: Data): AddFeedJob {
+        val feedUrl = requireNotNull(inputData.getString("url"))
+        val categoryId = inputData.getLong("categoryId", 0)
+        val feedLogin = inputData.getString("login") ?: ""
+        val feedPassword = inputData.getString("password") ?: ""
+        return addFeedJobFactory.create(feedUrl, categoryId, feedLogin, feedPassword)
+    }
+
+    companion object {
+        fun getInputData(account: Account,
+                         feedUrl: String,
+                         categoryId: Long = 0,
+                         feedLogin: String = "",
+                         feedPassword: String = ""): Data {
+            return workDataOf(
+                "account_name" to account.name,
+                "account_type" to account.type,
+                "url" to feedUrl,
+                "categoryId" to categoryId,
+                "login" to feedLogin,
+                "password" to feedPassword
+            )
+        }
+    }
+
+
+    class Factory @Inject constructor(
+        private val feedComponentBuilder: AddFeedComponent.Builder
+    ) : WorkerFactory() {
+        override fun createWorker(
+            appContext: Context, workerClassName: String, workerParameters: WorkerParameters
+        ): ListenableWorker? {
+
+
+            if (workerClassName != AddFeedWorker::class.java.name) {
+                return null
+            }
+            val account = with(workerParameters.inputData) {
+                val accountName = getString("account_name")
+                val accountType = getString("account_type")
+                Account(accountName, accountType)
+            }
+
+            val addFeedComponent = feedComponentBuilder.seedAccount(account).build()
+            return AddFeedWorker(appContext, workerParameters, addFeedComponent.addFeedJobFactory)
+        }
+    }
+
+}
--- a/app/src/main/java/com/geekorum/ttrss/add_feed/di.kt	Thu Jun 13 16:44:01 2019 -0700
+++ b/app/src/main/java/com/geekorum/ttrss/add_feed/di.kt	Fri Jun 14 14:20:41 2019 -0700
@@ -22,7 +22,10 @@
 
 import android.accounts.Account
 import androidx.lifecycle.ViewModel
+import androidx.work.WorkerFactory
 import com.geekorum.geekdroid.dagger.ViewModelKey
+import com.geekorum.geekdroid.dagger.WorkerInjectionModule
+import com.geekorum.geekdroid.dagger.WorkerKey
 import com.geekorum.ttrss.accounts.NetworkLoginModule
 import com.geekorum.ttrss.accounts.PerAccount
 import com.geekorum.ttrss.di.AssistedFactoriesModule
@@ -43,7 +46,7 @@
  *
  */
 
-@Module
+@Module(includes = [WorkerInjectionModule::class, AddFeedComponentModule::class])
 abstract class AndroidInjectorsModule {
 
     @ContributesAndroidInjector(modules = [AddFeedComponentModule::class])
@@ -52,16 +55,21 @@
     @ContributesAndroidInjector(modules = [ViewModelsModule::class])
     abstract fun contributeAddFeedActivityInjector(): AddFeedActivity
 
+    @Binds
+    @IntoMap
+    @WorkerKey(AddFeedWorker::class)
+    abstract fun providesAddFeedWorkerFactory(workerFactory: AddFeedWorker.Factory): WorkerFactory
+
 }
 
 
 @Module(subcomponents = [AddFeedComponent::class])
-private abstract class AddFeedComponentModule
+abstract class AddFeedComponentModule
 
 
 @Subcomponent(modules = [AssistedFactoriesModule::class, NetworkLoginModule::class, TinyrssApiModule::class])
 @PerAccount
-internal interface AddFeedComponent {
+interface AddFeedComponent {
 
     val addFeedJobFactory: AddFeedJob.Factory