Replace MessageActivity's AsyncTasks with Coroutines

This commit is contained in:
Niko Diamadis
2022-12-29 20:13:27 +01:00
parent 6aeb21ebc3
commit c32d6a81bd

View File

@@ -6,7 +6,6 @@ import android.graphics.Canvas
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.AsyncTask
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
@@ -31,6 +30,7 @@ import com.github.gotify.BuildConfig
import com.github.gotify.MissedMessageUtil
import com.github.gotify.R
import com.github.gotify.Utils
import com.github.gotify.Utils.launchCoroutine
import com.github.gotify.api.Api
import com.github.gotify.api.ApiException
import com.github.gotify.api.Callback
@@ -56,6 +56,8 @@ import com.google.android.material.navigation.NavigationView
import com.google.android.material.snackbar.BaseTransientBottomBar.BaseCallback
import com.google.android.material.snackbar.Snackbar
import java.io.IOException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
internal class MessagesActivity :
AppCompatActivity(),
@@ -74,7 +76,9 @@ internal class MessagesActivity :
messageJson,
Message::class.java
)
NewSingleMessage().execute(message)
launchCoroutine {
addSingleMessage(message)
}
}
}
@@ -126,8 +130,10 @@ internal class MessagesActivity :
override fun onDrawerClosed(drawerView: View) {
if (updateAppOnDrawerClose != null) {
viewModel.appId = updateAppOnDrawerClose!!
UpdateMessagesForApplication(true).execute(updateAppOnDrawerClose)
launchCoroutine {
updateMessagesForApplication(true, updateAppOnDrawerClose!!)
updateAppOnDrawerClose = null
}
invalidateOptionsMenu()
}
}
@@ -143,7 +149,9 @@ internal class MessagesActivity :
swipeRefreshLayout.isEnabled = true
}
}
UpdateMessagesForApplication(true).execute(viewModel.appId)
launchCoroutine {
updateMessagesForApplication(true, viewModel.appId)
}
}
override fun onPostCreate(savedInstanceState: Bundle?) {
@@ -167,7 +175,9 @@ internal class MessagesActivity :
private fun onRefresh() {
viewModel.messages.clear()
LoadMore().execute(viewModel.appId)
launchCoroutine {
loadMore(viewModel.appId)
}
}
private fun openDocumentation() {
@@ -175,10 +185,6 @@ internal class MessagesActivity :
startActivity(browserIntent)
}
fun commitDelete() {
CommitDeleteMessage().execute()
}
private fun onUpdateApps(applications: List<Application>) {
val menu: Menu = binding.navView.menu
menu.removeGroup(R.id.apps)
@@ -283,7 +289,9 @@ internal class MessagesActivity :
private fun doLogout() {
setContentView(R.layout.splash)
DeleteClientAndNavigateToLogin().execute()
launchCoroutine {
deleteClientAndNavigateToLogin()
}
}
private fun startLoading() {
@@ -303,7 +311,9 @@ internal class MessagesActivity :
val filter = IntentFilter()
filter.addAction(NEW_MESSAGE_BROADCAST)
registerReceiver(receiver, filter)
UpdateMissedMessages().execute(viewModel.messages.getLastReceivedMessage())
launchCoroutine {
updateMissedMessages(viewModel.messages.getLastReceivedMessage())
}
var selectedIndex: Int = R.id.nav_all_messages
val appId = viewModel.appId
if (appId != MessageState.ALL_MESSAGES) {
@@ -372,7 +382,9 @@ internal class MessagesActivity :
// deletion to be sent to the server twice, since the deletion is sent to the server
// in MessageFacade if a message is deleted while another message was already
// waiting for deletion.
commitDelete()
launchCoroutine {
commitDeleteMessage()
}
}
}
}
@@ -474,32 +486,24 @@ internal class MessagesActivity :
) {
if (!isLoadMore) {
isLoadMore = true
LoadMore().execute(viewModel.appId)
launchCoroutine {
loadMore(viewModel.appId)
}
}
}
}
}
}
private inner class UpdateMissedMessages : AsyncTask<Long?, Void?, Boolean>() {
override fun doInBackground(vararg ids: Long?): Boolean {
val id = ids.first()!!
if (id == -1L) {
return false
}
val newMessages = MissedMessageUtil(
viewModel.client.createService(
MessageApi::class.java
)
).missingMessages(id).filterNotNull()
private suspend fun updateMissedMessages(id: Long) {
if (id == -1L) return
val newMessages = MissedMessageUtil(viewModel.client.createService(MessageApi::class.java))
.missingMessages(id).filterNotNull()
viewModel.messages.addMessages(newMessages)
return newMessages.isNotEmpty()
}
override fun onPostExecute(update: Boolean) {
if (update) {
UpdateMessagesForApplication(true).execute(viewModel.appId)
}
if (newMessages.isNotEmpty()) {
updateMessagesForApplication(true, viewModel.appId)
}
}
@@ -512,7 +516,9 @@ internal class MessagesActivity :
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.action_delete_all) {
DeleteMessages().execute(viewModel.appId)
launchCoroutine {
deleteMessages(viewModel.appId)
}
}
if (item.itemId == R.id.action_delete_app) {
val alert = android.app.AlertDialog.Builder(this)
@@ -544,80 +550,50 @@ internal class MessagesActivity :
})
}
private inner class LoadMore : AsyncTask<Long?, Void?, List<MessageWithImage>>() {
override fun doInBackground(vararg appId: Long?): List<MessageWithImage> {
return viewModel.messages.loadMore(appId.first()!!)
}
override fun onPostExecute(messageWithImages: List<MessageWithImage>) {
updateMessagesAndStopLoading(messageWithImages)
private suspend fun loadMore(appId: Long) {
val messagesWithImages = viewModel.messages.loadMore(appId)
withContext(Dispatchers.Main) {
updateMessagesAndStopLoading(messagesWithImages)
}
}
private inner class UpdateMessagesForApplication(withLoadingSpinner: Boolean) :
AsyncTask<Long?, Void?, Long>() {
init {
private suspend fun updateMessagesForApplication(withLoadingSpinner: Boolean, appId: Long) {
if (withLoadingSpinner) {
withContext(Dispatchers.Main) {
startLoading()
}
}
override fun doInBackground(vararg appIds: Long?): Long {
val appId = appIds.first()!!
viewModel.messages.loadMoreIfNotPresent(appId)
return appId
}
override fun onPostExecute(appId: Long) {
withContext(Dispatchers.Main) {
updateMessagesAndStopLoading(viewModel.messages[appId])
}
}
private inner class NewSingleMessage : AsyncTask<Message?, Void?, Void?>() {
override fun doInBackground(vararg newMessages: Message?): Void? {
viewModel.messages.addMessages(listOfNotNull(*newMessages))
return null
private suspend fun addSingleMessage(message: Message) {
viewModel.messages.addMessages(listOf(message))
updateMessagesForApplication(false, viewModel.appId)
}
override fun onPostExecute(data: Void?) {
UpdateMessagesForApplication(false).execute(viewModel.appId)
}
}
private inner class CommitDeleteMessage : AsyncTask<Void?, Void?, Void?>() {
override fun doInBackground(vararg messages: Void?): Void? {
private suspend fun commitDeleteMessage() {
viewModel.messages.commitDelete()
return null
updateMessagesForApplication(false, viewModel.appId)
}
override fun onPostExecute(data: Void?) {
UpdateMessagesForApplication(false).execute(viewModel.appId)
}
}
private inner class DeleteMessages : AsyncTask<Long?, Void?, Boolean>() {
init {
private suspend fun deleteMessages(appId: Long) {
withContext(Dispatchers.Main) {
startLoading()
}
override fun doInBackground(vararg appId: Long?): Boolean {
return viewModel.messages.deleteAll(appId.first()!!)
}
override fun onPostExecute(success: Boolean) {
if (!success) {
val success = viewModel.messages.deleteAll(appId)
if (success) {
updateMessagesForApplication(false, viewModel.appId)
} else {
Utils.showSnackBar(this@MessagesActivity, "Delete failed :(")
}
UpdateMessagesForApplication(false).execute(viewModel.appId)
}
}
private inner class DeleteClientAndNavigateToLogin : AsyncTask<Void?, Void?, Void?>() {
override fun doInBackground(vararg ignore: Void?): Void? {
private fun deleteClientAndNavigateToLogin() {
val settings = viewModel.settings
val api = ClientFactory.clientToken(
settings.url, settings.sslSettings(), settings.token
)
val api = ClientFactory.clientToken(settings.url, settings.sslSettings(), settings.token)
.createService(ClientApi::class.java)
stopService(Intent(this@MessagesActivity, WebSocketService::class.java))
try {
@@ -638,15 +614,10 @@ internal class MessagesActivity :
} catch (e: ApiException) {
Log.e("Could not delete client", e)
}
return null
}
override fun onPostExecute(aVoid: Void?) {
viewModel.settings.clear()
startActivity(Intent(this@MessagesActivity, LoginActivity::class.java))
finish()
super.onPostExecute(aVoid)
}
}
private fun updateMessagesAndStopLoading(messageWithImages: List<MessageWithImage>) {