What determines when a view is actually displayed?

In my main activity, I call setContentView in onCreate. Then in onResume I start the service, if it is the first time in the service, it creates an alarm and stops. I expected the layout to appear when setContentView is called, but going through the debugger indicates that it does not appear until the service returns.

Should it display as soon as setContentView is called?

Edit

It seems that onWindowFocusChanged is not called at the beginning of the first application (MAIN / LAUNCHER). By debugging, it seems that the following happens: MAIN onCreate - onStart - onResume (this is where the service starts. SERVICE class - onStart - returns the service MAIN -onResume - onWindowsFocusChanged (the first screen appears)

The diagrams I saw say that the activity is visbile from onStart, but this is not like the first action. Is there a way to make the screen see in the open?

+7
source share
7 answers

The type of content is determined immediately after calling setContentView() , so you can start using findViewById() and administer the View user interface right here.

BUT

  • the view is not displayed until onResume() returns. This is actually one of the goals of onResume() : it is called every time the Activity runs in the foreground and, thus, directly in front of its user interface.

  • this does not mean that the user interface is displayed at this time , even if it is displayed. For example, it can be hidden using lockscreen. onWindowFocusChanged(true) is called when the user interface is actually visible (when it just gained focus).

So, the moment when the user interface is displayed both visible and visible is between onResume() (which is called immediately before) and onWindowFocusChanged(true) (which is called right after).

+6
source

Use AsyncTask and do invalidate () with your layout inside onPostExecute (). All user interface drawings are executed as soon as your control returns to the user interface manager when you return from your code. It is not possible to force redrawing without exiting the code, so people use AsyncTask or Handlers to do this.

My example:

 // this goes inside your OnCreate don't use OnResume or you need to start // your service each time apk resumes?? in that case put it inside // OnStart()<-- start service OnStop()<-- stop service @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // do your initializing chores in here..... setContenView(R.layout.mainlayout); UIUpate ui = new UIUpdate(); ui.execute(); } // define class somewhere in your code private class UIUpdate extends AsyncTask<Void,Void,Void>{ @Override protected Void doInBackground(Void... arg0) { // fire your service here StartMyService(); } @Override protected void onPostExecute(Void result) { //assuming you put your view inside a LinearLayout LinearLayout ll = (LinearLayout)findViewById(R.id.mylayout); // check that your topmost LinearLayout has an ID, top most hasn't by default ll.invalidate(); // program for update when this exit } 

If you analyze the programming pattern that I set above, you will see that it is not difficult. Whenever you need to update the user interface, you need to think that the stream is like this -> mycode () - Ui manager - mycodepart2 (), you need to break your code into two pieces, returning first to the UI manager and continuing in piece two.

The problem is that you have no control over how to execute piece two after exiting to the interface manager, so AsyncTask works well, PreExecute () do chunk1, PostExecute () does piece 2. Both parts execute inside the user interface thread, you can update any user interface. doInBackground () is its other kind of animal, executed in its own thread and cannot update the interface.

+4
source

There is no onCreate method, the action is only initialized. The actual activity mapping happens somewhere before onWindowFocusChanged . From the documents

Keep in mind that onResume is not the best indicator that your activity is visible to the user; A system window, such as a key lock, may be in front. Use onWindowFocusChanged (boolean) to know exactly what your activity is visible to the user (for example, to resume the game).

+2
source

You can use the public void onAttachedToWindow () Activity public void onAttachedToWindow () . This callback is called when the main activity-related window is associated with the window manager.

There is a version of View onAttachedToWindow() that is called when the view is attached to the window. At this moment he has a Surface and drawing will begin. Please note that this function is guaranteed to be called before onDraw(Canvas) , however, it can be called at any time before the first onDraw - including before or after onMeasure(int, int) .

View.onAttachedToWindow () Link

0
source

first there is something called the activity life cycle. LINK in accordance with this, your activity will be available only after onResume returns.

therefore, using AsyncTask ( LINK ), since the proposed mojo will help return a Resume request during a service call (in a separate thread).

so for your question. if you understand Activity Lifecyle , you will know what is happening.

so if you want to be displayed . then you can put the service call in AsyncTask and specify setContent in onCreate .

0
source

The layout is displayed immediately after calling onWindowFocusChanged() . So you need to do something after onWindowFocusChanged() . It is really easy.

 @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (!hasFocus) return; Handler h = new Handler(); Runnable r = new Runnable() { @Override public void run() { Log.v("[Testing]", "run() called"); //start your service here } }; h.post(r); } 
0
source

I am not an expert, but the easiest way to see if this view is displayed:

  if ( view.window ) { ... } 

Hope this helps!

0
source

All Articles