When activity will be visible? After onStart() or onResume()?
Asked Answered
W

3

6

Docs say:

The visible lifetime of an activity happens between a call to onStart() until a corresponding call to onStop().

Also in this one you can see:

The onStart() call makes the activity visible to the user ...

So I thought the UI of Activity must be visible after returning from onStart().

Recently, for testing purpose, I put an infinite loop in onResume() and guessed that the UI of Activity must be visible. But the result of starting Activity was a white window without any UI.

So it seems that UI of Activity will be visible after returning from onResume() instead of returning from onStart(). Is this true? If yes, why docs do say such misleading statements?

Edit:

You may think like Công Hải which says:

I think the documents mention about window visible not view visible.

But I do not think that "visibility" means above mentioned "white window"; because if you put an infinite loop in onCreate(), result of starting Activity again will be a white window, while as docs say the onCreate() is not in "visible lifetime" of Activity. So "visibility of Activity" must mean another thing than "white window".

Edit2

Alongside official docs, many tutorials say the Activity will be visible by calling onStart() and interactive by calling onResume(). Are they all say incorrect thing without testing?

Watanabe answered 31/7, 2020 at 6:27 Comment(5)
I think the documents mention about window visible not view visible.Acnode
@CôngHải Please see my edit.Watanabe
Ok, agree with your statement, let see others explain itAcnode
"Called when the activity is becoming visible to the user. Followed by onResume() if the activity comes to the foreground, or onStop() if it becomes hidden." In your document you put, I read it's "becoming" not already visible, what happen if you put loop inside onResume?Acnode
@CôngHải As I mentioned in question, putting infinite loop in onResume() and starting the Activity, causes a frozen white window.Watanabe
K
2

Putting an infinite loop in onResume() is not really going to tell you the whole story. There are a lot of activities that are queued to the main (UI) thread (like painting the screen) and since onResume() is called on the main (UI) thread you are preventing Android from doing any work on the main (UI) thread. This is why you see a white (or black) screen in this case.

To answer your question, Activity will be visible after onResume().

Kwabena answered 1/8, 2020 at 20:33 Comment(6)
You say:"Putting an infinite loop in onResume() is not really going to tell you the whole story". I think it is enough for testing when the Activity will be visible. Are you agree?Watanabe
@ You say:"Activity will be visible after onResume()", so you belive docs are here misleading?Watanabe
Putting an infinite loop does not work to test if the Activity will be visible. It may now be visible, but because you have blocked the main (UI) thread, nothing can be drawn, so you actually can't see the Activity. This test is invalid and is not conclusive.Kwabena
I can understand that you say the docs are misleading. Unfortunately a lot of the Android documentation is misleading, incorrect, confusing and/or conflicting. A lot depends on what it means to be "visible". If you see a white window then we can say that the Activity is visible, because you no longer see the HOME screen. However, the framework still needs to measure and draw all of your Views for the UI to actually appear visible to the user. So this is just a matter of semantic definition of the word "visible".Kwabena
Documentation says visible life time starts from onStart method. But there is no resource which states that activity becomes visible at perticular time whether it be before making call to onStart or during onStart or just after onStart.Ic
What I assume is after making call to onStart it starts the process to make activity visible and when it ends we don't know.Ic
H
2

Take a closer look at the docs that you linked. It states:

If an activity has lost focus but is still presented to the user, it is visible. It is possible if a new non-full-sized or transparent activity has focus on top of your activity, another activity has higher position in multi-window mode, or the activity itself is not focusable in current windowing mode. Such activity is completely alive (it maintains all state and member information and remains attached to the window manager).

If an activity is completely obscured by another activity, it is stopped or hidden. It still retains all state and member information, however, it is no longer visible to the user so its window is hidden and it will often be killed by the system when memory is needed elsewhere.

[...]

The visible lifetime of an activity happens between a call to onStart() until a corresponding call to onStop(). During this time the user can see the activity on-screen, though it may not be in the foreground and interacting with the user. Between these two methods you can maintain resources that are needed to show the activity to the user. For example, you can register a BroadcastReceiver in onStart() to monitor for changes that impact your UI, and unregister it in onStop() when the user no longer sees what you are displaying. The onStart() and onStop() methods can be called multiple times, as the activity becomes visible and hidden to the user.

This paints a pretty clear picture of what is meant by "visible": Your activity controls at least a part of what is shown on the screen.

With blocking onResume you have prevented your activity from launching as normal and/or rendering your content but it is still visible to the user (the white screen) and obscuring a previously visible activity.

Hughie answered 7/8, 2020 at 12:18 Comment(4)
As I mentioned in question " if you put an infinite loop in onCreate(), result of starting Activity again will be a white window" it means that the Activity controls a part of screen. So from your prospect it is "visible" in onCreate(); but it violates this statement: "The visible lifetime of an activity happens between a call to onStart() until a corresponding call to onStop()".Watanabe
You stated that you put the loop in onResume which is inside the "visible lifetime". Where is the contradiction?Hughie
Just saw your edit. Well here we have to return to the fact that these callbacks are only hooks for you, dispatched by the system. Thus if you decide to block a callback like that it is up to the system how to react to this. In short this behavior is undefined. The system was just giving you a heads up that your activity would be visible soon. I find it interesting that this is what ends up happening. But I would not rely on it or use it to draw deeper conclusions.Hughie
Btw what you see is not just a white screen but the windowBackground as specified in your theme.Hughie
R
0

Please look at the activity life-cycle.

enter image description here

The activity is visible and running between onResume() and onPause(). For more info refer this docs.

Now coming back to why you see white screen.

Views are drawn asynchronously - meaning that execution of your code does not wait until views are drawn. If onResume() is called before all the views are rendered and your infinity loop starts - it will eat up all the computing power and your UI will not be rendered.

Let me make it more clear. Why you ask about views not showing when placing infinite loop in onResume? why don't you ask why views are not created even though infinite loop comes after setContentView in onCreate itself?

To further point-out the source of your misunderstanding -- you think that onStart and onResume are called only after views are created. This is not true. onStart and onResume can be called even before drawing of views is not completed. So, the situation could be that your views may exist in memory but are not yet rendered.

One more things worth noting

  1. It is not mandatory to call setContentView() in onCreate, you can call it even in onStart or onResume

If for some reason you want to wait for a particulate view to be drawn before doing something, you must run your code in postRunnable

yourView.post(new Runnable({
   public void run(){
   // do your stuff
   }
}));
Room answered 10/8, 2020 at 9:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.