mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 15:56:48 +08:00
fix: save action is not invalidated when 'Quick run' action is executed (#1369)
This commit is contained in:
@@ -17,13 +17,9 @@
|
||||
|
||||
package com.itsaky.androidide.actions
|
||||
|
||||
import android.text.TextUtils
|
||||
import com.itsaky.androidide.lookup.Lookup
|
||||
import com.itsaky.androidide.projects.builder.BuildService
|
||||
import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult
|
||||
import com.itsaky.androidide.tooling.api.messages.result.TaskExecutionResult.Failure.UNKNOWN
|
||||
import com.itsaky.androidide.utils.ILogger
|
||||
import com.itsaky.androidide.utils.flashError
|
||||
|
||||
/**
|
||||
* Marker class for actions that execute build related tasks.
|
||||
@@ -44,49 +40,5 @@ abstract class BaseBuildAction : EditorActivityAction() {
|
||||
} else {
|
||||
visible = true
|
||||
}
|
||||
|
||||
if (isBuildInProgress()) {
|
||||
enabled = false
|
||||
return
|
||||
} else {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
fun shouldPrepare() = visible && enabled
|
||||
|
||||
private fun isBuildInProgress(): Boolean {
|
||||
return buildService == null || buildService?.isBuildInProgress == true
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
protected fun execTasks(
|
||||
data: ActionData,
|
||||
resultHandler: (TaskExecutionResult?) -> Unit = {},
|
||||
vararg tasks: String,
|
||||
) {
|
||||
|
||||
val buildService = this.buildService ?: return
|
||||
if (!buildService.isToolingServerStarted()) {
|
||||
flashError(R.string.msg_tooling_server_unavailable)
|
||||
return
|
||||
}
|
||||
|
||||
val activity =
|
||||
data.getActivity()
|
||||
?: run {
|
||||
resultHandler(TaskExecutionResult(false, UNKNOWN, ""))
|
||||
return
|
||||
}
|
||||
|
||||
activity.saveAllAsync()
|
||||
|
||||
buildService.executeTasks(tasks = tasks).whenComplete { result, err ->
|
||||
if (result == null || err != null) {
|
||||
log.error("Tasks failed to execute", TextUtils.join(", ", tasks))
|
||||
}
|
||||
|
||||
resultHandler(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,11 @@ package com.itsaky.androidide.actions
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import com.itsaky.androidide.activities.editor.EditorHandlerActivity
|
||||
import com.itsaky.androidide.tasks.cancelIfActive
|
||||
import kotlinx.coroutines.CoroutineName
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.plus
|
||||
|
||||
/** @author Akash Yadav */
|
||||
abstract class EditorActivityAction : ActionItem {
|
||||
@@ -32,16 +37,25 @@ abstract class EditorActivityAction : ActionItem {
|
||||
|
||||
override var requiresUIThread: Boolean = false
|
||||
|
||||
protected val actionScope = CoroutineScope(Dispatchers.Default) +
|
||||
CoroutineName("${javaClass.simpleName}Scope")
|
||||
|
||||
override fun prepare(data: ActionData) {
|
||||
if (!data.hasRequiredData(Context::class.java)) {
|
||||
markInvisible()
|
||||
}
|
||||
}
|
||||
|
||||
fun ActionData.getActivity() : EditorHandlerActivity? {
|
||||
fun ActionData.getActivity(): EditorHandlerActivity? {
|
||||
return this[Context::class.java] as? EditorHandlerActivity
|
||||
}
|
||||
fun ActionData.requireActivity() : EditorHandlerActivity {
|
||||
|
||||
fun ActionData.requireActivity(): EditorHandlerActivity {
|
||||
return getActivity()!!
|
||||
}
|
||||
|
||||
override fun destroy() {
|
||||
super.destroy()
|
||||
actionScope.cancelIfActive("Action is being destroyed")
|
||||
}
|
||||
}
|
||||
|
||||
+43
-11
@@ -21,7 +21,9 @@ import android.content.Context
|
||||
import android.graphics.ColorFilter
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.PorterDuffColorFilter
|
||||
import android.text.TextUtils
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.itsaky.androidide.R.string
|
||||
import com.itsaky.androidide.actions.ActionData
|
||||
import com.itsaky.androidide.actions.BaseBuildAction
|
||||
import com.itsaky.androidide.actions.getContext
|
||||
@@ -39,6 +41,10 @@ import com.itsaky.androidide.utils.ApkInstaller
|
||||
import com.itsaky.androidide.utils.InstallationResultHandler
|
||||
import com.itsaky.androidide.utils.flashError
|
||||
import com.itsaky.androidide.utils.resolveAttr
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
@@ -114,21 +120,47 @@ class QuickRunWithCancellationAction(context: Context, override val order: Int)
|
||||
log.info(
|
||||
"Running task '$taskName' to assemble variant '${variant.name}' of project '${module.path}'")
|
||||
|
||||
execTasks(
|
||||
data,
|
||||
resultHandler = { result ->
|
||||
executeAsyncProvideError({ handleResult(data, result, module, variant) }) { _, error ->
|
||||
if (error != null) {
|
||||
log.error("Failed to process task execution result", error)
|
||||
}
|
||||
}
|
||||
},
|
||||
taskName
|
||||
)
|
||||
onModuleSelected(data, module, variant, taskName)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private fun onModuleSelected(
|
||||
data: ActionData,
|
||||
module: AndroidModule,
|
||||
variant: BasicAndroidVariantMetadata,
|
||||
taskName: String
|
||||
) {
|
||||
|
||||
val buildService = this.buildService ?: return
|
||||
if (!buildService.isToolingServerStarted()) {
|
||||
flashError(string.msg_tooling_server_unavailable)
|
||||
return
|
||||
}
|
||||
|
||||
val activity =
|
||||
data.getActivity()
|
||||
?: run {
|
||||
log.debug("Cannot start build. Activity instance not provided in ActionData.")
|
||||
return
|
||||
}
|
||||
|
||||
actionScope.launch(Dispatchers.Default) {
|
||||
activity.saveAllResult()
|
||||
|
||||
val result = withContext(Dispatchers.IO) {
|
||||
buildService.executeTasks(taskName).get()
|
||||
}
|
||||
|
||||
if (result?.isSuccessful != true) {
|
||||
log.error("Tasks failed to execute: '$taskName'")
|
||||
return@launch
|
||||
}
|
||||
|
||||
handleResult(data, result, module, variant)
|
||||
}
|
||||
}
|
||||
|
||||
private fun cancelBuild(): Boolean {
|
||||
log.info("Sending build cancellation request...")
|
||||
val builder = Lookup.getDefault().lookup(BuildService.KEY_BUILD_SERVICE)
|
||||
|
||||
@@ -319,31 +319,33 @@ open class EditorHandlerActivity : ProjectHandlerActivity(), IEditorHandler {
|
||||
|
||||
override fun saveAllAsync(
|
||||
notify: Boolean,
|
||||
requestSync: Boolean,
|
||||
processResources: Boolean,
|
||||
progressConsumer: ((Int, Int) -> Unit)?,
|
||||
runAfter: (() -> Unit)?
|
||||
) {
|
||||
activityBackroundScope.launch {
|
||||
saveAll(notify, processResources, progressConsumer)
|
||||
saveAll(notify, requestSync, processResources, progressConsumer)
|
||||
runAfter?.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun saveAll(
|
||||
notify: Boolean,
|
||||
requestSync: Boolean,
|
||||
processResources: Boolean,
|
||||
progressConsumer: ((Int, Int) -> Unit)?
|
||||
): Boolean {
|
||||
val result = saveAllResult(progressConsumer)
|
||||
|
||||
// don't bother to switch the context if we don't need to
|
||||
if (notify || result.gradleSaved) {
|
||||
if (notify || (result.gradleSaved && requestSync)) {
|
||||
withContext(Dispatchers.Main) {
|
||||
if (notify) {
|
||||
flashSuccess(string.all_saved)
|
||||
}
|
||||
|
||||
if (result.gradleSaved) {
|
||||
if (result.gradleSaved && requestSync) {
|
||||
editorViewModel.isSyncNeeded = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ interface IEditorHandler {
|
||||
*/
|
||||
suspend fun saveAll(
|
||||
notify: Boolean = true,
|
||||
requestSync: Boolean = true,
|
||||
processResources: Boolean = false,
|
||||
progressConsumer: ((progress: Int, total: Int) -> Unit)? = null
|
||||
) : Boolean
|
||||
@@ -62,6 +63,7 @@ interface IEditorHandler {
|
||||
*/
|
||||
fun saveAllAsync(
|
||||
notify: Boolean = true,
|
||||
requestSync: Boolean = true,
|
||||
processResources: Boolean = false,
|
||||
progressConsumer: ((progress: Int, total: Int) -> Unit)? = null,
|
||||
runAfter: (() -> Unit)? = null
|
||||
|
||||
Reference in New Issue
Block a user