My fix for black window when resuming android activity (stuck at app onPause)

Hi folks,

sometimes my android app was not able to resume right after pausing (using the back nav key), but not every time. I could not clarify what was causing it (i’m attaching the main component to opengl, so maybe that’s a reason, …

When it happened the app just showed as black window on resume. I figured out, that in these cases the app was not suspended right when pausing before. The JUCE message handling thread seemed not to be stuck.

I’m working with the up-to-date JUCE 4.2.1 from github.

But i could fix it by luck: in the Activity java code i changed the onPause() mehtod to the following:

@Override
protected void onPause()
{
	suspendApp();
	try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }
	super.onPause();
}`

Since that, the problem never occurred again.

1 Like

OK… interesting! But what’s actually going on there? Why did you try adding a sleep?

Well, I’m not sure what’s causing it. But when I was debugging (Android Studio) and set a breakpoint after
suspendApp();
, then the problem never occured. So I presumed that native call might need some more time to finish. When the problem arised (black sceen on resuming the app) and I stop the debugger, the thread report looks like this (still waiting in surfaceDestroyedNative):

"Juce Message Thread@3975" prio=5 runnable
  java.lang.Thread.State: RUNNABLE
	  at de.tud.inf.audiometer.MultitoneAudiometer$NativeSurfaceView.surfaceDestroyedNative(MultitoneAudiometer.java:-1)
	  at de.tud.inf.audiometer.MultitoneAudiometer$NativeSurfaceView.surfaceDestroyed(MultitoneAudiometer.java:856)
	  at android.view.SurfaceView.updateWindow(SurfaceView.java:567)
	  at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:239)
	  at android.view.View.dispatchWindowVisibilityChanged(View.java:9647)
	  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1309)
	  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1309)
	  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1309)
	  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1309)
	  at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1309)
	  at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1383)
	  at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
	  at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
	  at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
	  at android.view.Choreographer.doCallbacks(Choreographer.java:670)
	  at android.view.Choreographer.doFrame(Choreographer.java:606)
	  at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
	  at android.os.Handler.handleCallback(Handler.java:739)
	  at android.os.Handler.dispatchMessage(Handler.java:95)
	  at android.os.Looper.loop(Looper.java:148)
	  at android.app.ActivityThread.main(ActivityThread.java:5417)
	  at java.lang.reflect.Method.invoke(Method.java:-1)
	  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
	  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

"FinalizerDaemon@4023" daemon prio=5 waiting
  java.lang.Thread.State: WAITING
	 blocks FinalizerDaemon@4023
	  at java.lang.Object.wait(Object.java:-1)
	  at java.lang.Object.wait(Object.java:423)
	  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:101)
	  - locked <0xfc8> (a java.lang.ref.ReferenceQueue)
	  at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:72)
	  at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:185)
	  at java.lang.Thread.run(Thread.java:818)

"FinalizerWatchdogDaemon@4021" daemon prio=5 waiting
  java.lang.Thread.State: WAITING
	 blocks FinalizerWatchdogDaemon@4021
	  at java.lang.Object.wait(Object.java:-1)
	  at java.lang.Daemons$FinalizerWatchdogDaemon.waitForObject(Daemons.java:255)
	  - locked <0xfc7> (a java.lang.Daemons$FinalizerWatchdogDaemon)
	  at java.lang.Daemons$FinalizerWatchdogDaemon.run(Daemons.java:227)
	  at java.lang.Thread.run(Thread.java:818)

"ReferenceQueueDaemon@4019" daemon prio=5 waiting
  java.lang.Thread.State: WAITING
	 blocks ReferenceQueueDaemon@4019
	  at java.lang.Object.wait(Object.java:-1)
	  at java.lang.Daemons$ReferenceQueueDaemon.run(Daemons.java:147)
	  - locked <0xbdc> (a java.lang.Class)
	  at java.lang.Thread.run(Thread.java:818)

"HeapTaskDaemon@4022" daemon prio=5 waiting for monitor entry
  java.lang.Thread.State: BLOCKED
	  at dalvik.system.VMRuntime.runHeapTasks(VMRuntime.java:-1)
	  at java.lang.Daemons$HeapTaskDaemon.run(Daemons.java:355)
	  at java.lang.Thread.run(Thread.java:818)

"Pool@4003" prio=5 runnable
  java.lang.Thread.State: RUNNABLE
	  at de.tud.inf.audiometer.MultitoneAudiometer$JuceThread.runThread(MultitoneAudiometer.java:-1)
	  at de.tud.inf.audiometer.MultitoneAudiometer$JuceThread.run(MultitoneAudiometer.java:1293)

"Juce Timer@4006" prio=7 runnable
  java.lang.Thread.State: RUNNABLE
	  at de.tud.inf.audiometer.MultitoneAudiometer$JuceThread.runThread(MultitoneAudiometer.java:-1)
	  at de.tud.inf.audiometer.MultitoneAudiometer$JuceThread.run(MultitoneAudiometer.java:1293)

"Signal Catcher@4018" daemon prio=5 waiting
  java.lang.Thread.State: WAITING
	 Incompatible thread state: thread not suspended

"Binder_1@4020" prio=5 runnable
  java.lang.Thread.State: RUNNABLE
	 Incompatible thread state: thread not suspended

"Binder_2@4024" prio=5 runnable
  java.lang.Thread.State: RUNNABLE
	 Incompatible thread state: thread not suspended

"Binder_3@4017" prio=5 runnable
  java.lang.Thread.State: RUNNABLE
	 Incompatible thread state: thread not suspended

This is probably caused from drawing to the OpenGL context after the app is suspended. Giving the app 1s more time allows finalized rendering/animations to happen and complete.

For some the 1000ms time wait may be enough, depending on your app style. However its kind of a hack that does not really address the issue of allowing rendering to happen after an app is suspended.

I cannot attest if that part has been fixed in the latest tip as I am still using 3.0 (modified to my uses).

It would be really good to know if this still occurs on the latest branch (master or develop). We rewrote most of the OpenGL thread handling on Android to avoid the bug that you are reporting.

1 Like