previous activity state after launching new activity in its onCreate method? - android

Can any one explains what happens if I execute this activity?
I am getting weird output and app is hanging.
public class ComedyAct extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new ProgressBar(this));
startActivity(new Intent(this,secondact.class));
Log.d("main","I am after start second act");
int i=0;
while(i<10000);
}
#Override
protected void onStart() {
super.onStart();
int i=0;
while(i<10000);
Log.d("main","I am in start first act");
}
#Override
protected void onStop() {
super.onStop();
int i=0;
while(i<10000);
Log.d("main","I am in stop first act");
}
}

I would suggest you to read the activity life cycle...
when you start another activity, the ComedyAct activity will be in stop state, onStart will never call in this case..
Activity life cycle is:
OnCreate---> OnStart--->OnResume
when another activity launches
then first of all onPause---->onStop--->onDestroy
when first activity will be on resume?
first of all onCreate---->--->onStart---->onResume, if activity is destroyed...
But if the activity is not destroyed..then first of all onRestart--->onStart--->OnResume, in this case onCreate will never be called...

Related

Why does my Android onRestoreInstanceState method never get called eventough I save the activity state?

I have a surface view gameView, which gets loaded in this GameViewActivity.
I save a few values in the onSaveInstanceState method.
And when I leave this activity and come back the OnCreate() gets called again, reverting my activity back to its original state
and the onRestoreInstanceState never gets called.
On top of that, when I check the Bundle that gets passed into the OnCreate method its always null. Any idea, im very much stuck here?
public class GameViewActivity extends AppCompatActivity {
private int player;
private GridView grid1;
private GridView grid2;
private GameView gameView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
grid1 = new GridView(Constants.NUMBER_COLUMN_TILES, Constants.NUMBER_ROW_TILES);
grid2 = new GridView(Constants.NUMBER_COLUMN_TILES, Constants.NUMBER_ROW_TILES);
} catch(Exception e){
e.printStackTrace();
}
this.player = 1;
gameView = new GameView(this, "sea", grid1);
setContentView(gameView);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("tiles_player1", grid1.getTiles());
outState.putSerializable("tiles_player2", grid2.getTiles());
outState.putInt("player", player);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
grid1.setTiles((HashMap<Coordinate,GameTile>) savedInstanceState.get("tiles_player1"));
grid2.setTiles((HashMap<Coordinate,GameTile>) savedInstanceState.get("tiles_player2"));
player = (int)savedInstanceState.get("player");
}
onSaveInstance/onRestoreInstance are designed to store the activity state only when system kills it (e.g. low memory when app is in background). So if you leave the activity by navigating back (e.g. by pressing the Back button) - it is not going to call onSaveInstanceState and then onRestoreInstanceState when you open activity again. Instead you should persist activity data in SharedPreferences or sqlite or file (let's say in onStop() method).

Android return to app call method

I just recently started learning how to build android apps, and encountered a problem:
I want, when users leave the app (go to the homescreen, multitask), and they return, that the app calls a certain method. How can I do that?
This problem is more tricky than it may look like. When you return to app after leaving it, then is called method onResume of activity which was active when app was interrupted. But same happens when you go from one activity to another (onResume of second activity is called). If you just call method from onResume, it will be called every time onResume of any activity is called.
Take a look at this solution...
First, you have BaseActivity which is extended by all activities that need to call that method:
abstract public class BaseActivity extends Activity implements IName {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
if (AppClass.getPausedActivity() != null) {
if (this.getClassName().equals(AppClass.getPausedActivity()))
//call specific method
}
AppClass.setPausedActivity("");
super.onResume();
}
#Override
protected void onPause() {
AppClass.setPausedActivity(this.getClassName());
super.onPause();
}
#Override
abstract public String getClassName();
}
As you can see it implements interface IName:
public interface IName
{
String getClassName();
}
BaseActivity in onPause (when it is interrupted) calls setPausedActivity method of AppClass which remembers last activity name that was interrupted. In onResume (when app and activity is continued) we compare name of current activity and last paused activity.
So, when app is interrupted, these names will be same because you paused one activity and you got back to the same one. When you call activity from some other activity these names will not be same and method will not be called.
Here is code for AppClass:
public class AppClass extends Application {
public static String pausedActivity;
public static String getPausedActivity() {
return pausedActivity;
}
public static void setPausedActivity(String _pausedActivity) {
pausedActivity = _pausedActivity;
}
}
Also, here is example of activity that extends BaseActivity:
public class MainActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
}
//here you set name of current activity
#Override
public String getClassName() {
return "MainActivity";
}
}
You are bound to the Activity lifecycle. You will need to implement corresponding logic to figure out if the user has been in your app before (i.e. using SharedPreferences).

Calling finish() in onStop()

What happens when finish() method is called in onStop() method?
Does it causes anr : means it calls
onPause()->onStop()->finish()->onPause()....
or it finishes the activity : means it calls directly
onDestroy()
Actually, I want to finish my activity when it is completely invisible.
EDIT:
See this scenario, I launch an activity B whose layout height and
width is smaller than activity A, so activity A is partially visible
and when I press the home button activity A becomes completely
invisible. At this point I want to close activity A, so that it do not
call onRestart().
Thanks in advance.
It finishes the activity and onDestroy() is called. If you want to finish your activity when it is invisible then you should call finish() in onStop().
according to your scenario, maintain one flag in MainActivity indicating that other Activity is launched or not? and make sure yourself to finish MainActivity or not based on that flag ...
this may help you...
public class MyActivity extends Activity {
private boolean isSecondActivityLaunched;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
isSecondActivityLaunched = false;
}
public void onClick(View view) {
Intent intent = new Intent(this, SecondActivity.class);
startActivity(intent);
isSecondActivityLaunched = true;
}
#Override
protected void onStop() {
super.onStop();
if(!isSecondActivityLaunched) {
finish();
}
}
}
It will be best way in your case to call finish() ;
Thanks

onCreate flow continues after finish()

I would like to finish an activity from inside the onCreate method. When I call finish(), onDestroy() is not immediately called, the code keeps flowing past finish(). onDestroy() isn't called until after the onCreate() closing brace.
Per the onCreate() description at developer.android.com/reference.
You can call finish() from within this function, in which case
onDestroy() will be immediately called without any of the rest of the
activity lifecycle (onStart(), onResume(), onPause(), etc) executing.
Reason I ask is: I would like to check data from the Bundle passed to onCreate(). Of course I have control of what is passed to onCreate, but I still think it should be checked at the point of delivery.
My code contains class A, which starts Activity B. I believe the last two "outside of if clause" tags, shouldn't be called because the finish method in the if statement should have destroyed the activity. It has nothing to do with the if clause because the tag line after the second finish() call is still also read.
My Code:
Class A
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// goToBButton: when pressed sends message to class B.
Button goToBButton = (Button)this.findViewById(R.id.go_to__b_btn);
goToBButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick (View v) {
Log.i(TAG,"A Class: goToBButton, onClick");
Intent i = new Intent(A.this, B.class);
startActivityForResult(i,REQ_TO_B);
}
});
} // end onCreate
My Code ClassB
public class B extends Activity{
private static final String TAG = "tag";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layoutb);
// set as true, should always print Tag: one line before first finish"
if (true) {
Log.i(TAG,"B Class: one line before 1st finish");
finish();
}
// shouldn't get here after first finish
Log.i(TAG,"B Class: outside of if clause, before second finish");
finish();
// shouldn't get here after second finish
Log.i(TAG,"B Class: outside of if clause, after finish");
} // end onCreate
#Override
public void onStart () {
super.onStart();
Log.i(TAG,"B Class: onStart");
}
#Override
public void onRestart() {
super.onRestart();
Log.i(TAG,"B Class: onRestart");
}
#Override
public void onResume () {
super.onResume();
Log.i(TAG,"B Class: onResume");
}
#Override
public void onPause () {
super.onPause();
Log.i(TAG,"B Class: onPause");
}
#Override
public void onStop () {
super.onStop();
Log.i(TAG,"B Class: onStop");
}
#Override
public void onDestroy () {
super.onDestroy();
Log.i(TAG,"B Class: onDestroy");
}
} // end B Class
Here are the results of my tags:
11-26 15:53:40.456: INFO/tag(699): A Class: goToBButton, onClick
11-26 15:53:40.636: INFO/tag(699): A Class: onPause
11-26 15:53:40.865: INFO/tag(699): B Class: one line before 1st finish
11-26 15:53:40.896: INFO/tag(699): B Class: outside of if clause,
before second finish
11-26 15:53:40.917: INFO/tag(699): B Class: outside of if clause,
after finish
11-26 15:53:41.035: INFO/tag(699): A Class: onResume
11-26 15:53:41.165: INFO/tag(699): B Class: onDestroy
I'm guessing that it is because finish() doesn't cause the onCreate method to return. You could try simply adding
finish();
return;
Or use an if else
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layoutb);
if(good data){
//do stuff
}else{
finish();
}
}
It seems like finish() does not work until onCreate() return control to system. Please refer to this post: about finish() in android. You have to consider this issue if you don't want any of your code to be executed after calling finish.
Hope it helps.

Saving Activity State

I have two activities A, B . Now from A i call B by pressing a button (using startActivity()) , then press Back key to go back to A . Now when i press Button again to go to B , fresh activity is called (as expected).
Now can someone tell me how to show old previous state of B ?
I have read this article
Saving Android Activity state using Save Instance State , but couldn't help myself :(
public class B extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main1);
if(savedInstanceState!=null){
EditText editText=(EditText)findViewById(R.id.editText1);
editText.setText(savedInstanceState.getString("EditBox"));
}
}
#Override
protected void onSaveInstanceState(Bundle onSaveInstanceState) {
System.out.println("B.onSaveInstanceState()");
super.onSaveInstanceState(onSaveInstanceState);
onSaveInstanceState.putString("EditBox","Hello");
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
System.out.println("B.onRestoreInstanceState()");
super.onRestoreInstanceState(savedInstanceState);
EditText editText=(EditText)findViewById(R.id.editText1);
editText.setText(savedInstanceState.getString("EditBox"));
}}
My Class A
public class A extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button=(Button)findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i=new Intent(StartActivityforresultActivity.this,B.class);
startActivity(i);
}
});
}
With what it sounds like you're trying to do you have two options:
1. Save the state of B when B's onDestroy or onBackPressed is called. You'll have to save this to memory or write it out using some sort of persistence (SharedPreferences, local file, etc). Then whenever B is started, check to see if that data exists and use it to load the state.
2. Override onBackPressed so that when it is pressed you aren't calling super.onBackPressed. Instead start an instance of activity A and set your intent's flags to be FLAG_ACTIVITY_REORDER_TO_FRONT before calling startActivity. So something like this:
Intent intent = new Intent(this, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
Now when you hit back, it should find the instance of A that is in your activity stack and just bring it to the front. You may have to add the same flag whenever you start B as well.

Categories

Resources