diff --git a/app/build.gradle b/app/build.gradle index 79e70b241c..a0c72dcba9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,10 +15,11 @@ if (!isAndroidTestBuild()) { logLevel "DEBUG" } } - -apply plugin: 'chain.log.hook' -hooklog{ - enableLoggerToServer true +if (!isAndroidTestBuild()) { + apply plugin: 'chain.log.hook' + hooklog{ + enableLoggerToServer true + } } //if (!isAndroidTestBuild()) { diff --git a/app/src/androidTest/java/com/mogo/functions/test/AutoPilotBadCaseTest.kt b/app/src/androidTest/java/com/mogo/functions/test/AutoPilotBadCaseTest.kt index eece9eae07..29a8fd3427 100644 --- a/app/src/androidTest/java/com/mogo/functions/test/AutoPilotBadCaseTest.kt +++ b/app/src/androidTest/java/com/mogo/functions/test/AutoPilotBadCaseTest.kt @@ -5,7 +5,7 @@ import androidx.test.core.app.ActivityScenario import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import com.mogo.eagle.core.data.autopilot.AutoPilotRecordResult -import com.mogo.eagle.core.function.hmi.ui.MoGoHm·iFragment +import com.mogo.eagle.core.function.hmi.ui.MoGoHmiFragment import com.mogo.eagle.core.function.main.MainLauncherActivity import kotlinx.coroutines.* import kotlinx.coroutines.flow.* diff --git a/app/src/androidTest/java/com/mogo/functions/test/TipToastLeakTest.kt b/app/src/androidTest/java/com/mogo/functions/test/TipToastLeakTest.kt new file mode 100644 index 0000000000..49b38265e5 --- /dev/null +++ b/app/src/androidTest/java/com/mogo/functions/test/TipToastLeakTest.kt @@ -0,0 +1,71 @@ +package com.mogo.functions.test + +import androidx.test.core.app.ActivityScenario +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.LargeTest +import com.mogo.eagle.core.function.hmi.ui.MoGoHmiFragment +import com.mogo.eagle.core.function.main.MainLauncherActivity +import com.mogo.eagle.core.utilcode.mogo.toast.TipToast +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.suspendCancellableCoroutine +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit +import java.util.concurrent.TimeUnit.MILLISECONDS + +@RunWith(AndroidJUnit4::class) +@LargeTest +class TipToastLeakTest { + + + lateinit var launch: ActivityScenario + + @Before + fun before() { + launch = ActivityScenario.launch(MainLauncherActivity::class.java) + + } + + @Test + fun test() = runBlocking(Dispatchers.Main) { + val f = ensureMoGoHmiFragmentShow() + var index = 0 + while (index < 50) { + delay(TimeUnit.SECONDS.toMillis(4)) + TipToast.shortTip("toast-> $index" ) + index ++ + } + delay(TimeUnit.SECONDS.toMillis(1)) + f.activity?.finish() + delay(TimeUnit.SECONDS.toMillis(2)) + } + + private suspend fun ensureMoGoHmiFragmentShow(): MoGoHmiFragment = suspendCancellableCoroutine { + launch.onActivity { itx -> + val executor = Executors.newSingleThreadScheduledExecutor() + executor.scheduleAtFixedRate({ + var find = + itx.supportFragmentManager.fragments.find { it is MoGoHmiFragment } as? MoGoHmiFragment + while (find == null) { + find = + itx.supportFragmentManager.fragments.find { it is MoGoHmiFragment } as? MoGoHmiFragment + + } + while (!find.isResumed) { + Thread.sleep(500) + } + it.resumeWith(Result.success(find)) + try { + Thread.sleep(500) + executor.shutdownNow() + } catch (e: Throwable) { + e.printStackTrace() + } + }, 50, 500, MILLISECONDS) + } + } +} \ No newline at end of file diff --git a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/kotlin/ExtensionKt.kt b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/kotlin/Extensions.kt similarity index 100% rename from core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/kotlin/ExtensionKt.kt rename to core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/kotlin/Extensions.kt diff --git a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/mogo/toast/TipToast.java b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/mogo/toast/TipToast.java index 1eb4e366ce..997abed4ae 100644 --- a/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/mogo/toast/TipToast.java +++ b/core/mogo-core-utils/src/main/java/com/mogo/eagle/core/utilcode/mogo/toast/TipToast.java @@ -17,6 +17,13 @@ import android.view.Gravity; import android.view.View; import android.widget.Toast; +import androidx.annotation.NonNull; +import androidx.core.view.ViewCompat; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.LifecycleEventObserver; +import androidx.lifecycle.LifecycleOwner; + +import com.mogo.eagle.core.utilcode.kotlin.ExtensionsKt; import com.mogo.eagle.core.utilcode.mogo.logger.Logger; @@ -34,7 +41,7 @@ public final class TipToast { private static ToastViewGenerator sGenerator; public static void init( Context context, ToastViewGenerator generator ) { - TipToast.sContext = context; + TipToast.sContext = context.getApplicationContext(); sHandler = new Handler( context.getMainLooper() ); sGenerator = generator; } @@ -165,20 +172,21 @@ public final class TipToast { sHandler.post(() -> { synchronized ( sSyncObject ) { - if ( context == null ) { return; } - - if ( sToast != null ) { - sToast.cancel(); + if ( sToast != null) { + View view = sToast.getView(); + if (view != null && ViewCompat.isAttachedToWindow(view)) { + sToast.cancel(); + } } - if ( sGenerator == null ) { sToast = Toast.makeText( context, msg, duration ); } else { sToast = new Toast( context ); final View view = sGenerator.make( context, msg, tipDrawable ); + if ( view != null ) { sToast.setView( view ); sToast.setGravity( sGenerator.gravity(), sGenerator.xOffset(), sGenerator.yOffset() ); @@ -187,6 +195,15 @@ public final class TipToast { sToast = Toast.makeText( context, msg, duration ); } } + View view = sToast.getView(); + if (view != null) { + LifecycleOwner lifecycleOwner = ExtensionsKt.getLifecycleOwner(view); + lifecycleOwner.getLifecycle().addObserver((LifecycleEventObserver) (source, event) -> { + if (event == Lifecycle.Event.ON_DESTROY) { + sToast = null; + } + }); + } if ( sToast != null ) { sToast.show(); }