diff options
author | Daniel Schaal <daniel@schaal.email> | 2021-07-18 18:42:02 +0300 |
---|---|---|
committer | Daniel Schaal <daniel@schaal.email> | 2021-07-25 10:10:47 +0300 |
commit | 8137abd31ec83204edb1ff9d47f49b22d9bb3351 (patch) | |
tree | 73e394305001aa65e519c58d11d93cca4ad8fc86 | |
parent | e8cb4c58e16bd96b914d93b0306b69e9725d6934 (diff) |
Use WorkManager to enqueue sync tasks
6 files changed, 69 insertions, 114 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index db4193c9..45547ed4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -79,11 +79,6 @@ android:name=".SettingsActivity" android:label="Settings" android:parentActivityName=".ListActivity" /> - - <service - android:name=".service.SyncJobIntentService" - android:exported="false" - android:permission="android.permission.BIND_JOB_SERVICE" /> </application> </manifest>
\ No newline at end of file diff --git a/app/src/main/java/email/schaal/ocreader/ListActivity.kt b/app/src/main/java/email/schaal/ocreader/ListActivity.kt index 3b891dc1..9c23b2bd 100644 --- a/app/src/main/java/email/schaal/ocreader/ListActivity.kt +++ b/app/src/main/java/email/schaal/ocreader/ListActivity.kt @@ -35,10 +35,12 @@ import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar.OnMenuItemClickListener import androidx.databinding.DataBindingUtil +import androidx.lifecycle.LiveData import androidx.lifecycle.Observer import androidx.preference.PreferenceManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener +import androidx.work.WorkInfo import com.google.android.material.snackbar.Snackbar import com.mikepenz.aboutlibraries.LibsBuilder import email.schaal.ocreader.R.string @@ -49,8 +51,8 @@ import email.schaal.ocreader.database.model.Item import email.schaal.ocreader.database.model.TemporaryFeed import email.schaal.ocreader.database.model.TreeItem import email.schaal.ocreader.databinding.ActivityListBinding -import email.schaal.ocreader.service.SyncResultReceiver import email.schaal.ocreader.service.SyncType +import email.schaal.ocreader.service.SyncWorker import email.schaal.ocreader.view.* import email.schaal.ocreader.view.TreeItemsAdapter.TreeItemClickListener @@ -60,7 +62,6 @@ class ListActivity : AppCompatActivity(), ItemViewHolder.OnClickListener, OnRefr private lateinit var binding: ActivityListBinding private lateinit var adapter: LiveItemsAdapter private lateinit var layoutManager: LinearLayoutManager - private lateinit var syncResultReceiver: SyncResultReceiver private val feedViewModel: FeedViewModel by viewModels { FeedViewModelFactory(this) } private lateinit var preferenceChangeListener: OnSharedPreferenceChangeListener @@ -103,7 +104,6 @@ class ListActivity : AppCompatActivity(), ItemViewHolder.OnClickListener, OnRefr override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.activity_list) - syncResultReceiver = SyncResultReceiver(binding.listviewSwitcher) setSupportActionBar(binding.toolbarLayout.toolbar) val preferences = PreferenceManager.getDefaultSharedPreferences(this) val menuItemShowOnlyUnread = binding.bottomAppbar.menu.findItem(R.id.menu_show_only_unread) @@ -123,7 +123,7 @@ class ListActivity : AppCompatActivity(), ItemViewHolder.OnClickListener, OnRefr true } R.id.menu_sync -> { - feedViewModel.sync(this, SyncType.FULL_SYNC, syncResultReceiver) + observeWork(feedViewModel.sync(this, SyncType.FULL_SYNC)) true } R.id.menu_about -> { @@ -185,6 +185,17 @@ class ListActivity : AppCompatActivity(), ItemViewHolder.OnClickListener, OnRefr } } + private fun observeWork(workLiveData: LiveData<WorkInfo>) { + workLiveData.observe(this, { info -> + if(info != null && info.state.isFinished) { + info.outputData.getString(SyncWorker.KEY_EXCEPTION)?.let { + Snackbar.make(binding.listviewSwitcher, + it, Snackbar.LENGTH_LONG).show() + } + } + }) + } + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putParcelable(LAYOUT_MANAGER_STATE, layoutManager.onSaveInstanceState()) @@ -228,7 +239,7 @@ class ListActivity : AppCompatActivity(), ItemViewHolder.OnClickListener, OnRefr } if(result.first == Activity.RESULT_OK) { Queries.resetDatabase() - feedViewModel.sync(this, SyncType.FULL_SYNC, syncResultReceiver) + observeWork(feedViewModel.sync(this, SyncType.FULL_SYNC)) } } @@ -300,7 +311,7 @@ class ListActivity : AppCompatActivity(), ItemViewHolder.OnClickListener, OnRefr } override fun onRefresh() { - feedViewModel.sync(this, SyncType.FULL_SYNC, syncResultReceiver) + observeWork(feedViewModel.sync(this, SyncType.FULL_SYNC)) } override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { diff --git a/app/src/main/java/email/schaal/ocreader/database/FeedViewModel.kt b/app/src/main/java/email/schaal/ocreader/database/FeedViewModel.kt index d18aae8e..48a343b6 100644 --- a/app/src/main/java/email/schaal/ocreader/database/FeedViewModel.kt +++ b/app/src/main/java/email/schaal/ocreader/database/FeedViewModel.kt @@ -22,13 +22,16 @@ import android.content.Context import android.content.SharedPreferences import androidx.lifecycle.* import androidx.preference.PreferenceManager +import androidx.work.OneTimeWorkRequestBuilder +import androidx.work.WorkInfo +import androidx.work.WorkManager +import androidx.work.workDataOf import email.schaal.ocreader.Preferences import email.schaal.ocreader.database.model.* import email.schaal.ocreader.database.model.TemporaryFeed.Companion.getListTemporaryFeed import email.schaal.ocreader.putBreadCrumbs -import email.schaal.ocreader.service.SyncJobIntentService -import email.schaal.ocreader.service.SyncResultReceiver import email.schaal.ocreader.service.SyncType +import email.schaal.ocreader.service.SyncWorker import io.realm.Realm import io.realm.kotlin.where import kotlin.IllegalArgumentException @@ -57,8 +60,13 @@ class FeedViewModel(context: Context) : RealmViewModel() { val user: LiveData<User> get() = userLiveData - fun sync(context: Context, syncType: SyncType, resultReceiver: SyncResultReceiver? = null) { - SyncJobIntentService.enqueueWork(context, syncType, resultReceiver) + fun sync(context: Context, syncType: SyncType): LiveData<WorkInfo> { + val workManager = WorkManager.getInstance(context) + val syncWork = OneTimeWorkRequestBuilder<SyncWorker>() + .setInputData(workDataOf(SyncWorker.KEY_SYNC_TYPE to syncType.action)) + .build() + workManager.enqueue(syncWork) + return workManager.getWorkInfoByIdLiveData(syncWork.id) } fun updateFolders(onlyUnread: Boolean) { diff --git a/app/src/main/java/email/schaal/ocreader/service/SyncChangesWorker.kt b/app/src/main/java/email/schaal/ocreader/service/SyncChangesWorker.kt deleted file mode 100644 index 115189ad..00000000 --- a/app/src/main/java/email/schaal/ocreader/service/SyncChangesWorker.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright © 2020. Daniel Schaal <daniel@schaal.email> - * - * This file is part of ocreader. - * - * ocreader 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. - * - * ocreader 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 Foobar. If not, see <http://www.gnu.org/licenses/>. - */ - -package email.schaal.ocreader.service - -import android.content.Context -import androidx.work.CoroutineWorker -import androidx.work.WorkerParameters -import email.schaal.ocreader.api.API - -class SyncChangesWorker(val context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams) { - override suspend fun doWork(): Result { - API(context).sync(SyncType.SYNC_CHANGES_ONLY) - return Result.success() - } -}
\ No newline at end of file diff --git a/app/src/main/java/email/schaal/ocreader/service/SyncJobIntentService.kt b/app/src/main/java/email/schaal/ocreader/service/SyncJobIntentService.kt deleted file mode 100644 index 2b2ac441..00000000 --- a/app/src/main/java/email/schaal/ocreader/service/SyncJobIntentService.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright © 2020. Daniel Schaal <daniel@schaal.email> - * - * This file is part of ocreader. - * - * ocreader 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. - * - * ocreader 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 Foobar. If not, see <http://www.gnu.org/licenses/>. - */ - -package email.schaal.ocreader.service - -import android.content.Context -import android.content.Intent -import android.os.Bundle -import android.os.ResultReceiver -import androidx.core.app.JobIntentService -import androidx.preference.PreferenceManager -import email.schaal.ocreader.Preferences -import email.schaal.ocreader.api.API -import email.schaal.ocreader.service.SyncResultReceiver.Companion.EXCEPTION_DATA_KEY -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch - -class SyncJobIntentService: JobIntentService() { - companion object { - const val SYNC_TYPE_EXTRA = "email.schaal.ocreader.SYNC_TYPE" - const val JOB_ID = 12345 - - fun enqueueWork(context: Context, syncType: SyncType, resultReceiver: SyncResultReceiver?) { - val intent = Intent() - intent - .putExtra(SYNC_TYPE_EXTRA, syncType.action) - .putExtra(SyncResultReceiver.INTENT_KEY,resultReceiver) - enqueueWork(context, SyncJobIntentService::class.java, JOB_ID, intent) - } - } - - override fun onHandleWork(intent: Intent) { - val syncType = SyncType[intent.getStringExtra(SYNC_TYPE_EXTRA)] ?: SyncType.FULL_SYNC - val preferences = PreferenceManager.getDefaultSharedPreferences(this) - val syncResultReceiver = intent.getParcelableExtra<ResultReceiver>(SyncResultReceiver.INTENT_KEY) - - if(syncType != SyncType.SYNC_CHANGES_ONLY) - preferences.edit().putBoolean(Preferences.SYS_SYNC_RUNNING.key, true).apply() - - GlobalScope.launch { - try { - API(this@SyncJobIntentService).sync(syncType) - } catch (e: Exception) { - e.printStackTrace() - syncResultReceiver?.send(0, Bundle().apply { putSerializable(EXCEPTION_DATA_KEY, e) }) - } - }.invokeOnCompletion { - preferences.edit().putBoolean(Preferences.SYS_SYNC_RUNNING.key, false).apply() - } - } -}
\ No newline at end of file diff --git a/app/src/main/java/email/schaal/ocreader/service/SyncWorker.kt b/app/src/main/java/email/schaal/ocreader/service/SyncWorker.kt new file mode 100644 index 00000000..0039482b --- /dev/null +++ b/app/src/main/java/email/schaal/ocreader/service/SyncWorker.kt @@ -0,0 +1,40 @@ +package email.schaal.ocreader.service + +import android.content.Context +import androidx.preference.PreferenceManager +import androidx.work.CoroutineWorker +import androidx.work.WorkerParameters +import androidx.work.workDataOf +import email.schaal.ocreader.Preferences +import email.schaal.ocreader.api.API +import email.schaal.ocreader.util.LoginError + +class SyncWorker(context: Context, workerParams: WorkerParameters) : CoroutineWorker(context, workerParams) { + companion object { + const val KEY_SYNC_TYPE = "KEY_SYNC_TYPE" + const val KEY_EXCEPTION = "KEY_EXCEPTION" + } + + override suspend fun doWork(): Result { + val syncType: SyncType = SyncType[inputData.getString(KEY_SYNC_TYPE)] ?: SyncType.FULL_SYNC + val preferences = PreferenceManager.getDefaultSharedPreferences(applicationContext) + + if(syncType != SyncType.SYNC_CHANGES_ONLY) + preferences.edit().putBoolean(Preferences.SYS_SYNC_RUNNING.key, true).apply() + + return try { + API(applicationContext).sync(syncType) + Result.success() + } catch (e: Throwable) { + e.printStackTrace() + Result.failure( + workDataOf( + KEY_EXCEPTION to LoginError.getError( + applicationContext, e).message + ) + ) + } finally { + preferences.edit().putBoolean(Preferences.SYS_SYNC_RUNNING.key, false).apply() + } + } +}
\ No newline at end of file |