Android Activity life cycle, print methods, save and restore - android

Im really new to android and i have a little problem that i dont know how to solve.
Im having a small application that prints out the Activity lifes circles methods like this:
protected void onCreate(){
super.onStart()
print("onStart was called"); //this is a void and its only printing a text
}
protected void onStart(){
super.onStart()
print("onStart was called");
}
and so on...
While im i portrait mode the app is showing all the methods on the screen but when i switch to landscape the activity object is of course destroyed and it creates the first three methods again.
Im using onSaveInstanceState an onRestoeeInstaceState to try to save printed order on the screen while i switch from portrait to landscape.
How can i make it work?
example of app output in portrait mode:
onCreate was called
onStart was called
onResume was called
onPause was called
onStop was called
onRestart was called
onStart was called
onResume was called
i want theese prints to stay even if i switch to landscape.
This is onSaveInstanceState and onRestoreInstanceState i dont really know how to solve the problem here.
#Override
protected void onSaveInstanceState(Bundle savedInstanceState){
super.onSaveInstanceState(savedInstanceState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState){
super.onRestoreInstanceState(savedInstanceState);
}

If you go to the manifest I believe you are able to edit it to allow portrait and landscape displays and also have it recall the savedInstanceState. Sorry I can't give you a more detailed answer at the moment.

Related

When is an activity forcefully recreated?

The Android docs say that configuration changes can force an activity to be recreated, the most common change being a rotation. Now, there are some methods that can determine whether an activity is being destroyed to be recreated but all(?) of these methods are called after onStop() and aren't guaranteed or recommended for data saving purposes.
To give an example, there is an EditText activity which autosaves what they have written/updated if the user navigates away from the app via back button, app switch, e.t.c. However, the user might not want to save their changes when there is a configuration change so I need to be prepared for those cases.
When an activity is destroyed by the system because of configuration change onSaveInstanceState is called.
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
Store data that you want to persist in outState bundle.
Then you'll receive the stored data in onCreate and onRestoreInstanceState.
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
Use it to retrieve data you had stored in onSaveInstanceState earlier.
By default System saves the state of few widgets (EditText , TextView) on it's own and this magic happens in super.onSaveInstanceState().
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
So if you do not want to save the text in EditText , just do editText.setText("") before calling super.onSaveInstanceState().
Hope this helps.

Why isn't onRestoreInstanceState called after onStart?

I am trying to test onRestoreInstanceState method and when (exactly) it is called . So I have followed these steps :
start my activity. onCreate -- > onStart --> onResume were called .
press Home button on the emulator . onPause --> onSaveInstanceState --> onStop were called .
Click the icon in the launcher and launch my activity again. onRestart --> onStart --> onResume were called .
My java code :
package com.test.demostate.app;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
public class MainActivity extends ActionBarActivity {
private int visiters=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("TAG","onCreate");
}
#Override
protected void onPause() {
super.onPause();
Log.d("TAG","onPause");
}
#Override
protected void onStop() {
super.onStop();
Log.d("TAG","onStop");
}
#Override
protected void onStart() {
super.onStart();
Log.d("TAG","onStart");
}
#Override
protected void onRestart() {
super.onRestart();
Log.d("TAG","onRestart");
}
#Override
protected void onResume() {
super.onResume();
visiters++;
Log.d("TAG","onResume");
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("visiters",visiters);
Log.d("TAG",visiters+" visiters was saved ");
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
visiters=savedInstanceState.getInt("visiters");
Log.d("TAG",visiters+" visiters was restored");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.d("TAG","onDestroy");
}
}
From the docs : Instead of restoring the state during onCreate() you may choose to implement onRestoreInstanceState(), which the system calls after the onStart() method .
So onRestoreInstanceState is called
after the activity was destroyed onPause --> onStop --> onDestroy then onCreate --> onRestoreInstanceState --> onResume( due to screen rotation for example )
after the activity was stopped onPause --> onStop --> onRestart --> onStart --> onRestoreInstanceState --> onResume( due to home icon pressing for example )
But why isn't it called after onStart ?
Thanks
After onStart() only if onSaveInstanceState() has been called.
From the docs:
This method is called after onStart() when the activity is being
re-initialized from a previously saved state, given here in
savedInstanceState. Most implementations will simply use
onCreate(Bundle) to restore their state, but it is sometimes
convenient to do it here after all of the initialization has been done
or to allow subclasses to decide whether to use your default
implementation. The default implementation of this method performs a
restore of any view state that had previously been frozen by
onSaveInstanceState(Bundle).
This method is called between onStart() and onPostCreate(Bundle).
Activity#onRestoreInstanceState()
The official documentation says about onRestoreInstanceState (Bundle savedInstanceState):
This method is called after onStart() when the activity is being
re-initialized from a previously saved state, given here in
savedInstanceState. Most implementations will simply use
onCreate(Bundle) to restore their state, but it is sometimes
convenient to do it here after all of the initialization has been done
or to allow subclasses to decide whether to use your default
implementation. The default implementation of this method performs a
restore of any view state that had previously been frozen by
onSaveInstanceState(Bundle).
This method is called between onStart() and onPostCreate(Bundle).
When the activity is beign re-initialized?
When orientation of the device changes your activity is re-initialized.
When there is another activity in front of your app and the OS kills your app for some reason, may be for example free resources.
Try change the orientation of emulator:
Ctrl+F12
Look the answer of user #GAThrawn
Pressing the Home button you leave your app and go to the home screen,
whilst leaving your app running in the background. This is a bit like
switching between windows on a Windows PC.
Except that when your phone is running low on resources like memory it
will start to close apps that are running in the background, so that
your phone has enough resources for what you're trying to do now.
Games are often amongst the first apps the phone will "kill" to save
resources as they often use a lot more memory and CPU than other apps.
This is why sometimes your game is still running paused, and sometimes
Android has closed it for you.
So I can not prove my second argument, since it decides it is the OS, at least do not know how to prove.

onCreate called whenever I the screen autorotates

In my app, I use the onCreate() method to initialize various variables. However, whenever I rotate the device, and the screen auto-rotates, onCreate() is called again, which re-initialize my variables. Is that how it's supposed to work? Where should I put code that I only want to be run once, when I start the app?
The above answers will lock your Activity into a specific orientation, which is generally not proper behavior for an Android app.
What you should be doing is storing your activity's state so when it gets recreated you can repopulate the UI with the stored values.
protected void onSaveInstanceState (Bundle outState) {
super.onSaveInstanceState(outState);
// put your values in the Bundle
outState.putString("TextView1Text", textView1.getText()); // for example;
}
Then in your onCreate() method you can restore the values
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
textView.setText(savedInstanceState.getString("TextView1Text"));
}
}
This will also work when the user leaves the app via the home button or other means.
In the manifest put this line in all the activities that you want PORTRAIT
android:screenOrientation="portrait"

Values changing when app turns from portrait mode to landscape mode in android

I am working on android apps. My app should work both in portrait and landscape mode. I adjusted all the layouts by keeping all layout files in layout-lan folder. But now my issue is with functionality i.e when the app is changed to landscape mode the values of my parameters are changing and due to this I am getting crashes. i.e i kept a counter value but it is displaying wrong count value when turned to port-lan. Also the functionality is changing due to this.
Please help me in this regard.
Each time you rotate the devide, onCreate method is being called again. You can save the values by overriding onSavedInstanceState and get them back in onRestoreInstanceState or in onCreate method. For example:
save the value:
public void onSaveInstanceState(Bundle outState) {
outState.putBoolean("booleanValue", true);
}
restore the value (you can call this in onCreate as well):
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState != null && savedInstanceState.containsKey("booleanValue")) {
boolean myBoolean = savedInstanceState.getBoolean("booleanValue");
}
super.onRestoreInstanceState(savedInstanceState);
}
Your activity restarts every time the orientation changes.
You have to store your values in onSaveInstanceState and restore them in onRestoreInstanceState. You will find the details here: http://developer.android.com/guide/topics/resources/runtime-changes.html
those values change because the activity gets destroyed and re-built during rotation,
please check the developers guide on how to save your activity state.
http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState

onCreate not called

I have 2 Activities : First activity user clicks on a button which launches the 2nd activity. The 2nd Activity does all the work.
I launch the 2nd Activity as follows which is inside a onClickListener Inner Class and I have tried explicitly calling it with (FirstActivity.this,Simple.Class) but same thing happens.
Intent test = new Intent(arg0.getContext(),Simple.class);
startActivity(test);
On the emulator, I see the screen move over like its calling the 2nd activity but all I get is a black screen but nothing is loaded from my layout. I looked at logcat and I do see some binder thread failed messages. This is the onCreate function from my 2nd activity but I do not get any results from either the screen or logcat showing me that the Log functions were called:
public void onCreate(Bundle savedState)
{
Log.d("SimpleActivity","OnCreate Started");
super.onCreate(savedState);
setContentView(R.layout.simple);
Log.d("SimpleActivity","OnCreate Ended");
}
Note : I have called the base constructor in OnCreate() with super.onCreate(savedState) in my code above.
What happened to me was I was overriding the wrong onCreate method. I was overriding public void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) when I really needed to override protected void onCreate(#Nullable Bundle savedInstanceState). Maybe this might help someone!
It's possible that onCreate doesn't get called, if the activity has never been destroyed,
if for some reason an activity hangs around, next time its instantiated it is not recreated but resumed instead...
At least that's what im Dealing with right now in my code... Life cycle of Activities seem a good logical explanation.. However 99% of time I do rely on onCreate being called when startingActivity and it doesn't fail me....
Edit: And of course its because I wasn't calling finish() when exiting the activity. Doh.
This is not related to this certain issue, but also this can happen when activity is not declared in manifest file)
Be careful that if your method belongs to AppCompatActivity or Activity .
It is up to what you implemented to your Class
If you want to add lifecycle or any override methods, I recommend you to press
CTRL+O or do Code > Override methodsand there you can see where the method belongs
remove android:launchMode="singleTask" from manifest
you should #Override onCreate and add super.onCreate() in it
#Override
public void onCreate(Bundle savedState)
{
super.onCreate(savedState);
Log.d("SimpleActivity","OnCreate Started");
setContentView(R.layout.simple);
Log.d("SimpleActivity","OnCreate Ended");
}
my case
(1) mainActivity -> (2) open Adaptor - startActivity -> (3) mainActivity onCreate() doesn't get to triggered.
I resolved this by adding finish();. in mainActivity.
follow the below steps to check your application.
1.did you override the right method? if not overriding the below method, this method will be triggered, when you startActivity.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
2.Make sure that you registered the activity in manifest.xml
2.1 is your activity has android:launchMode="singleInstance" ?
(if your application doesn't need to be singleinstance, consider to remove.
but my case I need singleinstance. hence i moved to the next step)
use finish()
public void openSearch(View view) {
Intent intent = new Intent(this, BookInfoActivity.class);
intent.putExtra(...);
startActivity(intent);
finish(); // add like this.}
why do we need to use "finish()"?
Screen A -> click button on A -> Screen B -> click button on B -> screen A with some new data that you get from Screen B
if you don't call finish() method(in A button) , that means the A is still in your background
even you are seeing the screen B.
hence, when you trigger startActivity on screen B, it just simply shows the running A screen.
however if you use finish() method (in A button), when you go to B Screen,
it destroys the A screen, so when you go back to A screen by clicking B method( 'StartActivity') it creates A screen and trigger onCreate() Method .
You need to call the super.onCreate(savedState) method. Take a look at Activity doc.
public void onCreate(Bundle savedState)
{
super.onCreate(savedState);
}

Categories

Resources