Espresso test error: AppNotIdleException - android

I turned off all animations on developer options.
But I still get this exception when trying to click on one of the buttons.
My app is indeed active and not idle entirely, but I can't change it.
android.support.test.espresso.AppNotIdleException: Looped for 6930
iterations over 60 SECONDS. The following Idle Conditions failed .
at dalvik.system.VMStack.getThreadStackTrace(Native Method)
at java.lang.Thread.getStackTrace(Thread.java:580)
at android.support.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:92)
at android.support.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:56)
at android.support.test.espresso.ViewInteraction.runSynchronouslyOnUiThread(ViewInteraction.java:184)
at android.support.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:115)
at android.support.test.espresso.ViewInteraction.perform(ViewInteraction.java:87)

I have been struggling with this problem for the last few days.
Here is a method that I used to identify "violators":
private void dumpThreads() {
int activeCount = Thread.activeCount();
Thread[] threads = new Thread[activeCount];
Thread.enumerate(threads);
for (Thread thread : threads) {
System.err.println(thread.getName() + ": " + thread.getState());
for (StackTraceElement stackTraceElement : thread.getStackTrace()) {
System.err.println("\t" + stackTraceElement);
}
}
}
In my case, Facebook SDK was using the AsyncTask thread pool.

In my case this problem was happening with AnimatedVectorDrawable and caused by an objectAnimator that was set to repeat the animation infinitely (android:repeatCount="infinite"). .
The problem was also present only on older platform versions. Tests were perfectly working on Android 9 while the problem was reproducible on Android 5 and 6 (not sure about 7 and 8 at the moment).
I believe, the root cause of the problem is the same as for indeterminate progress bars (covered in this SO question). However, I haven't found any nice solution, only workarounds.
One of the workarounds is to detect that the animation is turned off (animator duration is 0) in the setting and don't start the animation. Of course, this only works for platform versions where the animation does not autostart.
private fun startIconAnimation(imageView: ImageView) {
if (areAnimationsEnabled()) {
(imageView.drawable as Animatable).start()
}
}
private fun areAnimationsEnabled(): Boolean {
val animatorDurationScale = Settings.Global.getFloat(
requireContext().contentResolver,
Settings.Global.ANIMATOR_DURATION_SCALE,
1.0f
)
return animatorDurationScale != 0.0f
}
Note: API level 26 introduced a static method ValueAnimator.areAnimatorsEnabled() which would have been handy if the problem was not happening only on the older platform versions.

As per answer by MaciejGórski to the similar question:
It was a bug in my app code, where SwipeRefreshLayout animated
itself indefinitely. Due to a bug in this
component,
the refresh state was not even showing.

In my case I clicked "save" button running long request in a test. To complete the test I had to add idle() after save() method. But often it was not enough, a loader continued drawing and the test failed. Then I increased a duration: idle(10000) and got the error: androidx.test.espresso.AppNotIdleException: Looped for 238 iterations over 10 SECONDS. The following Idle Conditions failed DELAY_HAS_PAST..
I wrote: idle(5000). Instead of Espresso I use Kakao and Kaspresso.

Related

Android Test cases can only be debugged in debug mode after 10 minutes of waiting

It was working before. But now it doesn't anymore. The IDE just shows "Instantiating tests...". But when I wait for 10 minutes, then all of a sudden it does work? The machine is a Macbook Pro, Mid 2015. The problem only occurs on androidTest, the test directory works fine.
#LargeTest
#RunWith(AndroidJUnit4::class)
class SomeTestClass {
#get:Rule
var activityTestRule = ActivityTestRule(
NavigationActivity::class.java, false, false)
#Before
fun before() {
Timber.d("When debugging, this triggers only after about 10 minutes.")
}
#Test
fun testContents() {
Assert.assertEquals(0, 0)
}
}
The log keeps outputting this:
D/EZIO_NLOG: watchdog_routine executed!
D/EZIO_NLOG: check1
check1
check2
check2
Tried the following things:
File, Invalidate Cache / Restart
Tried this answer. But it seems to be outdated.
Edit Configurations..., Selected "All in Package", "Class" and "Method". None of them work.
When I wait really long, like 10 minutes, then all of a sudden it triggers and works.
Android Tests are slow and on top of that debugger adds more load to it. I have faced the same problem and I agree that using a debugger with Android Tests is a pain.
Below is something I found here
Espresso detects when the main thread is idle, so it is able to run your test commands at the appropriate time, improving the reliability of your tests.
and on top of that when a debugger is added it makes it more slow.
You can try running the tests on a real device it should be bit faster(I am assuming)

setVideoPath Illegal State Exception

I'm running through a slideshow in an infinite loop. Every 'x' amount of time, I switch the video playing. First I stop the video, and then I load the new video. My app is crashing when I set the video path, with an error that there is an illegal state. It only happens once every couple thousand uses, so I cannot replicate it. That is, if I leave the app open for 24 hours on 100 devices, it will happen once per day on one device.
runOnUiThread() {
if (mVideoView!!.isPlaying) {
mVideoView!!.stopPlayback()
}
mVideoView!!.setVideoPath(filePath)
mVideoView!!.setOnErrorListener { mp, what, extra ->
LOG.e("Media player error: $what extra: $extra")
// Something's wrong, try again
slideshowHandler.removeCallbacksAndMessages(null)
slideshowHandler.postDelayed(slideshowRunner, 0)
true
}
if (startTime > 0) {
mVideoView!!.seekTo(startTime)
}
mVideoView!!.start()
}
}
java.lang.IllegalStateException
at android.media.MediaPlayer.prepareAsync(Native Method)
at android.widget.VideoView.openVideo(VideoView.java:356)
at android.widget.VideoView.setVideoURI(VideoView.java:265)
at android.widget.VideoView.setVideoURI(VideoView.java:248)
at android.widget.VideoView.setVideoPath(VideoView.java:239)
Any thoughts on what this could be? What state is invalid? Am I doing things in the wrong order?
I can't find any similar issues on SO. The app is running lollipop 5.1 (has to).
Edit: I'm fixing this right now using a try/catch. Seems like there is some underlying bug in Android that is causing this.

Kotlin in Flutter application causing Crash

Since the last flutter update there has been an issue when I try to use the media player plugin witch uses Kotlin.
When you hit the button and it is suppose to play the audio file, it causes the application to crash.
fun play(url: String) {
player.reset()
channel.invokeMethod("onPosition", 0.0)
player.setDataSource(url)
player.prepareAsync()
channel.invokeMethod("onIsLoading", null)
task?.cancel()
task = object : TimerTask() {
override fun run() {
if (player.isPlaying) {
session.setPlaybackState(PlaybackStateCompat.Builder()
.setState(PlaybackStateCompat.STATE_PLAYING, player.currentPosition.toLong(), 1f)
.build())
channel.invokeMethod("onPosition", player.currentPosition.toDouble() / player.duration.toDouble())
}
}
}
timer.schedule(task, 0, 100)
}
it was suggested that I add this in.
activity.runOnUiThread(java.lang.Runnable {
channel.invokeMethod(...)
})
but I if I do I get
Unresolved Reference: activity
This is the error message.
java.lang.RuntimeException: Methods marked with #UiThread must be executed on the main thread. Current thread: Timer-0
at io.flutter.embedding.engine.FlutterJNI.ensureRunningOnMainThread(FlutterJNI.java:605)
at io.flutter.embedding.engine.FlutterJNI.dispatchPlatformMessage(FlutterJNI.java:515)
at io.flutter.embedding.engine.dart.DartMessenger.send(DartMessenger.java:76)
at io.flutter.embedding.engine.dart.DartExecutor.send(DartExecutor.java:166)
at io.flutter.view.FlutterNativeView.send(FlutterNativeView.java:155)
at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:98)
at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:84)
at live.exit.musicplayer.MusicPlayer$play$1.run(MusicPlayer.kt:49)
at java.util.TimerThread.mainLoop(Timer.java:562)
at java.util.TimerThread.run(Timer.java:512)
I am at a bit of a loss, this is suppose to be playing audio.
I know NOTHING about kotlin.
I think you're using ragotrebor music-player plugin (https://gitlab.com/ragotrebor). Looking at their history a merge was made about a month ago which should fix this issue.
Just update to the latest version of the plugin and you should be good to go!
Background
It's related to a change in flutter to fix a bug which caused FlutterJNI (Java Native Interface) to crash intermittently when certain methods were executed outside of the main thread. Flutter was changed to thrown an exception in all cases, to avoid this intermittent crash and force developers to run methods correctly on the UI thread. Unfortunately this caused many existing plugins to crash and developers were required to update their source code.
Reference links
Change with discussion: https://github.com/flutter/engine/commit/2c9e37c34e79475bbde7c8163eb5e56cdb9662a
Found through this thread discussing a fix for a specific plugin: https://github.com/flutter/flutter/issues/34993).
Merge request details for music player plugin that fixed this issue: https://gitlab.com/exitlive/music-player/commit/693131a7f0d29b3ee42ba9fa2a5ce65aef7652fb

Android: Possible maximum number of audiosessions or effect engines for audio? (EQ, REV...)

for awhile now, I am working on a media playing app. In this app, I also programmed a little 5 Band EQ using mainly this code:
try
{
AppPreferencesClass ap = new AppPreferencesClass(ctx);
if (Activity_Player.eq != null)
{
Activity_Player.eq.Dispose();
}
Activity_Player.eq = new Android.Media.Audiofx.Equalizer(0, Activity_Player.mediaPlayerSessionId);
Activity_Player.eq.SetEnabled(true);
await Task.Run(() =>
{
if (Activity_Player.EqActive)
{
if (ap.getAwesomeSound())
{
Activity_Player.eq.SetBandLevel(0, Convert.ToInt16(Activity_Equalizer.awesomesound0));
Activity_Player.eq.SetBandLevel(1, Convert.ToInt16(Activity_Equalizer.awesomesound1));
Activity_Player.eq.SetBandLevel(2, Convert.ToInt16(Activity_Equalizer.awesomesound2));
Activity_Player.eq.SetBandLevel(3, Convert.ToInt16(Activity_Equalizer.awesomesound3));
Activity_Player.eq.SetBandLevel(4, Convert.ToInt16(Activity_Equalizer.awesomesound4));
}
else
{
Activity_Player.eq.SetBandLevel(0, Convert.ToInt16(ap.getEQ0()));
Activity_Player.eq.SetBandLevel(1, Convert.ToInt16(ap.getEQ1()));
Activity_Player.eq.SetBandLevel(2, Convert.ToInt16(ap.getEQ2()));
Activity_Player.eq.SetBandLevel(3, Convert.ToInt16(ap.getEQ3()));
Activity_Player.eq.SetBandLevel(4, Convert.ToInt16(ap.getEQ4()));
}
}
});
}
catch
{
}
For many days, this worked just fine but out of NO WHERE, the catch block sometimes gets activated. But only occasionally.On other times, try works fine but there are just no more changes to the audio being played. This is odd enough, since I never changed anything on this code after it starting working.
I then tried another phone (Samsung S4) on my code and the eq worked just perfectly.
So this got me googleing and I think I might have heard that there can only be as many audiosession IDs after you just would run out. I tested and the audio session ID used here is somewhere at 74,000.
So this could be an issue I thought but this would easialy be tested because I already had this very app running in the google play store just an older version of it. I am 100 percent positive, that in this version the EQ worked on my phone. Otherwise I would have not uploaded that version.
Anyway, I downloaded my old app from the play store and here we go:
It doesnt work anymore. The EQ in the old version also has simply NO effect on the audio. While ofcourse on my other phones this old version works perfectly.
Before I am going to reset my own personal phone I wanted to ask you guys if this could be infact the case.
Another thing is, that I am using many static variables in order to get the EQ to work right. Actually, the variable EQ itself is static. Do maybe static variables sort of leave a "trace" behind and maybe I have set the eq up just "too" many times? Although I am disposing of the object before intialising it again (see in my code).
Summing up:
1.) Can there maybe be a maxmium number of EQ or AudioSessionIDs and I have passed those?
2.) Can creating static variables over and over again in my code cause a memory leak so big, even deinstalling the app doesnt do anything?
Thank you!
This is the error log:
11-20 12:16:43.736 E/AudioEffect(16990): set(): AudioFlinger could not create effect, status: -38
11-20 12:16:43.736 E/AudioEffects-JNI(16990): Error setting AudioEffect
11-20 12:16:43.737 E/AudioEffect-JAVA(16990): Error code -19 when initializing AudioEffect.
Thread started: #311-20 12:16:43.745 V/MediaPlayerNative(16990): unrecognized message: (6, 0, 0)
After 2 days of googeling and trying evetything out, here is the issue:
NOT CALLING RELEASE() will have you eventually have to REBOOT your phone. It wont allow too many instances of an EQ to be set.
Solution:
if (eq != null)
{
eq.Release();
}

Why are my OnTriggerEnter2D events firing only on android in a situation they shouldnt be firing?

Related reddit thread
I have been struggling with a collision bug that only happens when I install the game on an android device.
I have a very simple game set up like air hockey. Some objects to represent paddles, a puck, a couple of end zones for scoring, and walls. Whenever I move one of the paddles and collide it against the puck at a very low velocity, my ontriggerenter2d events are firing on my end zones even though the puck is nowhere near the end zones. Here is my OnTriggerEnter2d function in my end zone controller script:
// EndZone
void OnTriggerEnter2D(Collider2D Other)
{
Debug.Log("EndZone::OnTriggerEnter2D " + playerNumber.ToString());
if (Other.gameObject.tag == "Puck")
{
Observer.SendMessage("Score", "" + playerNumber.ToString());
}
}
I'm not sure what other information could be relevant. I will provide anything asked for including my entire project if deemed necessary.
This bug only happens when I actually build to android, not when I run the game on desktop. Even if I'm using a tablet and unity remote to provide input.
Update: Some more information I just found out:
Code from my PaddleController connected to my paddles:
void OnCollisionEnter2D(Collision2D coll)
{
Debug.Log("PaddleController::OnCollisionEnter2D " + coll.gameObject.tag);
if (coll.gameObject.tag == "Puck")
{
// Commenting out the following "AddForce" statement causes the bug to not happen
coll.gameObject.GetComponent<Rigidbody2D>().AddForce(CurrVelocity);
SoundManager.RandomizeSfxPitch(click);
}
}
void OnCollisionStay2D(Collision2D coll)
{
if (coll.gameObject.tag == "Puck")
{
// Commenting out the following "AddForce" statement causes the bug to not happen
coll.gameObject.GetComponent<Rigidbody2D>().AddForce(CurrVelocity);
}
}

Categories

Resources