Guys I am stuck in a problem with these two methods:-
When I change the orientation of device and set the text in edit text after retriving the text from bundle,it does't work.But the same code is working in onrestoreStoreInstante method.
Please have a look at my code:-
public class LifeCycleActivity extends Activity implements OnClickListener {
/** Called when the activity is first created. */
EditText user;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
user=(EditText)findViewById(R.id.et_user);
if(savedInstanceState!=null){
String s =savedInstanceState.get("Key").toString();
user=(EditText)findViewById(R.id.et_user);
user.setText(savedInstanceState.get("Key").toString());
Toast.makeText(this, s,Toast.LENGTH_SHORT).show();
}
Toast.makeText(this, "onCreate",Toast.LENGTH_SHORT).show();
Button b=(Button)findViewById(R.id.button1);
b.setOnClickListener(this);
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Toast.makeText(this, "onSaveInstanceState",Toast.LENGTH_SHORT).show();
outState.putString("Key", "Deepak");
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//String s =savedInstanceState.get("Key").toString();
//user.setText(s);
Toast.makeText(this, "onRestoreInstanceState",Toast.LENGTH_SHORT).show();
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Toast.makeText(this, "onStart",Toast.LENGTH_SHORT).show();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Toast.makeText(this, "onResume",Toast.LENGTH_SHORT).show();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Toast.makeText(this, "onPause",Toast.LENGTH_SHORT).show();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Toast.makeText(this, "onStop",Toast.LENGTH_SHORT).show();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(this, "onDEstroy",Toast.LENGTH_SHORT).show();
}
#Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Toast.makeText(this, "onRestart",Toast.LENGTH_SHORT).show();
}
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
startActivity(new Intent(LifeCycleActivity.this,SecondActivity.class));
}
}
when I set the text in edit text in oncreate method after getting the value from Bundle,it doesn't work.But the same code works in onRestoreInstanceState() method.
According to me , it should work for oncreate also as we can get the Bundle class object there.
Please help me to sort out this problem..
EditText and most of other views have their own methods to save/restore their own data. So in general it's not necessary to save/restore them on your code.
You can see this here on the Android TextView source code (remember that EditText extends from TextView) on line 3546:
if (ss.text != null) {
setText(ss.text);
}
so the reason you can't set it onCreate and can do it onRestoreInstanceState it's because during your activity super.onRestoreInstanceState(savedInstanceState) the activity calls the EditText.onRestoreInstanceState and the EditText restore it self to the previous value.
You can see it happening on the Activity source code on line 940
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (mWindow != null) {
Bundle windowState = savedInstanceState.getBundle(WINDOW_HIERARCHY_TAG);
if (windowState != null) {
mWindow.restoreHierarchyState(windowState);
}
}
}
hope it helps.
Overview
onSaveInstanceState() is used to put the data to bundle
onRestoreInstanceState() is used to set the data available in
bundle to your activity
So do as follows:
i Guess until the activity is created onorientation change the
bundle is not available, that's way you are not able to retrieve it
in oncreate
Let the activity create in oncreate
Then restore the instance in onRestoreInstanceState
Hope this helps !
Related
I want to work on my data depending on what Lifecycle state I have.
For example, I want to do something, when the application was resumed.
How can I find out in what State is my app now?
Thanks for help.
in activity: if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) ... I think. If you're asking about async tasks.
For custom class you can use lifecycle from architecture components, first add library
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
then your custom class, for example
public class MyObserver implements LifecycleObserver {
#OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void connectListener() {
...
}
#OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void disconnectListener() {
...
}
}
and finally from your lifecycle container (activity/fragment)
myActivity.getLifecycle().addObserver(new MyObserver());
More info here https://developer.android.com/topic/libraries/architecture/lifecycle.html
There are predefined methods of an Activity.
Please review Life cycle of an Activity in Android.
Example code
public class LifeCycleActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Toast.makeText(LifeCycleActivity.this,"ON CREATE", Toast.LENGTH_SHORT).show();
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Toast.makeText(LifeCycleActivity.this,"ON START", Toast.LENGTH_SHORT).show();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Toast.makeText(LifeCycleActivity.this,"ON RESUME", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Toast.makeText(LifeCycleActivity.this,"ON PAUSE", Toast.LENGTH_SHORT).show();
}
#Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Toast.makeText(LifeCycleActivity.this,"ON RESTART", Toast.LENGTH_SHORT).show();
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Toast.makeText(LifeCycleActivity.this,"ON STOP", Toast.LENGTH_SHORT).show();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Toast.makeText(LifeCycleActivity.this,"ON DESTROY", Toast.LENGTH_SHORT).show();
}
}
Also read: - https://developer.android.com/guide/components/activities/activity-lifecycle.html
I'm trying to make a simple android game. I have a surfaceview named: surfaceviewgame, which is responsible for the drawing, updating and handling touch events of the game. At this point I'm checking if the gamestate is "game-over" in this surfaceview by setting the "pause" boolean to true. Now, I want to read this pause variable like this:
SurfaceViewGame v;
if(v.pause == true){
setcontentview(R.Layout.pause)
}
But I can't simply paste that if statement in the activity below. Does someone know how to approach this problem?
public class StartGame extends Activity {
SurfaceViewGame v;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
v = new SurfaceViewGame(this);
setContentView(v);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
v.pause();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
v.resume();
}
}
You can pass some callback object from your activity to your SurfaceView, or make your activity such a callback and notify it about any changes in game flow. Then in your callback method you can resolve next behaviour.
Ok, this one is really tricky to me. The idea of this is a time log for EMS. You press a button by the action taken, and it logs the time for later use. I managed to figure out how to save the TextView into a string. Now, how on earth do I save the logTime1.setEnabled(false); so that on rotation or on leaving the activity, it restores it disabled? Eventually I will have another button beside it that will allow you to edit which will unlock the button. Here is the code.
public class TimeLog extends Activity{
boolean logTimeDis1=true;
Button logTime1;
String time1;
TextView ivTimeStamp;
int counter=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.time_log);
logTime1 = (Button) findViewById(R.id.logTime1);
ivTimeStamp = (TextView) findViewById(R.id.ivTimeStamp);
if(savedInstanceState != null) logTime1.setEnabled(savedInstanceState.getBoolean("logTimeDis1", true));
logTime1.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
time1 = new SimpleDateFormat("HH:mm", Locale.US).format(new Date());
ivTimeStamp.setText(time1);
logTime1.setEnabled(false);
logTimeDis1 = false;
return false;
}
});
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
counter++;
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
outState.putString("ivTimeStamp", ivTimeStamp.getText().toString());
outState.putBoolean("logTimeDis1", logTimeDis1);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
ivTimeStamp.setText(savedInstanceState.getString("ivTimeStamp"));
}
}
So, in this line
if(savedInstanceState != null) logTime1.setEnabled(savedInstanceState.getBoolean("logTmeDis1", false));
you don't check if savedInstanceState contains logTmeDis1. Say, savedInstanceState is not null, but does not have logTmeDis1, you'll get false and your button locked. Actually, you don't have to check it in this case, just change false to true, and it should work correctly.
I want to study the Acitvity liftTimes ,then I have two Activities,called MainActivity and SecondActivity,and I set the launch mode to singleTask mode,the code below:
public class MainActivity extends Activity {
/** Called when the activity is first created. */
public static final String PREFS_NAME = "MyPrefsFile";
private TextView tv;
private Button bt;
private final static String TAG = "MainActivity";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e(TAG+"onCreate", "onCreate");
setContentView(R.layout.activity_main);
findViews();
tv.setText("MainActivity ID:" + this.toString());
bt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this,
SecondActivity.class);
startActivity(intent);
}
});
}
private void findViews() {
// TODO Auto-generated method stub
tv = (TextView) findViewById(R.id.textView);
bt = (Button) findViewById(R.id.turnBt);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
Log.e(TAG+"onRestoreInstanceState", "onRestoreInstanceState");
}
#Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.e(TAG+"onRestart", "onRestart");
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.e(TAG+"onStart", "onStart");
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.e(TAG+"onResume", "onResume");
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
Log.e(TAG+"onSaveInstanceState", "onSaveInstanceState");
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.e(TAG+"onPause", "onPause");
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.e(TAG+"onDestroy", "onDestroy");
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.e(TAG+"onStop", "onStop");
}
}
public class SecondActivity extends Activity{
private TextView tv;
private Button bt;
private final static String TAG = "SECONDACTIVITY";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Log.e(TAG, "onCreate");
setContentView(R.layout.second_layout);
findViews();
tv.setText("第二个界面的ID:"+this.toString());
bt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(SecondActivity.this, MainActivity.class);
startActivity(intent);
}
});
}
private void findViews() {
// TODO Auto-generated method stub
tv = (TextView)findViewById(R.id.textView);
bt = (Button) findViewById(R.id.turnBt);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
Log.e(TAG, "onRestoreInstanceState");
}
#Override
protected void onRestart() {
// TODO Auto-generated method stub
super.onRestart();
Log.e(TAG, "onRestart");
}
#Override
protected void onStart() {
// TODO Auto-generated method stub
super.onStart();
Log.e(TAG, "onStart");
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Log.e(TAG, "onResume");
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
Log.e(TAG, "onSaveInstanceState");
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
Log.e(TAG, "onPause");
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
Log.e(TAG, "onDestroy");
}
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
Log.e(TAG, "onStop");
}
}
step 1:
launch MainActivity;
the logcat show below:
10-22 13:56:59.704: E/MainActivityonCreate(4649): onCreate
10-22 13:56:59.735: E/MainActivityonStart(4649): onStart
10-22 13:56:59.736: E/MainActivityonResume(4649): onResume
step 2:
from MainActivity to SecondActivity;
the logcat show below:
10-22 14:03:52.452: E/MainActivityonPause(4884): onPause
10-22 14:03:52.462: E/SECONDACTIVITY(4884): onCreate
10-22 14:03:52.485: E/SECONDACTIVITY(4884): onStart
10-22 14:03:52.485: E/SECONDACTIVITY(4884): onResume
10-2214:03:52.773:E/MainActivityonSaveInstanceState(4884): onSaveInstanceState
10-22 14:03:52.774: E/MainActivityonStop(4884): onStop
step 3:
from SecondActivity to MainActivity
the logcat show below:
10-22 14:05:14.561: E/SECONDACTIVITY(4884): onPause
10-22 14:05:14.574: E/MainActivityonCreate(4884): onCreate
10-22 14:05:14.592: E/MainActivityonStart(4884): onStart
10-22 14:05:14.593: E/MainActivityonResume(4884): onResume
10-22 14:05:14.877: E/SECONDACTIVITY(4884): onSaveInstanceState
10-22 14:05:14.877: E/SECONDACTIVITY(4884): onStop
step 4:
from MainActivity to SecondActivity
the logcat show below:
10-22 14:05:51.049: E/MainActivityonPause(4884): onPause
10-22 14:05:51.061: E/SECONDACTIVITY(4884): onRestart
10-22 14:05:51.061: E/SECONDACTIVITY(4884): onStart
10-22 14:05:51.061: E/SECONDACTIVITY(4884): onResume
10-22 14:05:51.330: E/MainActivityonStop(4884): onStop
10-22 14:05:51.330: E/MainActivityonDestroy(4884): onDestroy
my question:why the step 4,the MainActivity call the onDestroy() method ?
someone help me?
I tried your code and my onDestroy() Method does not gets called.
In your case onDestroy gets called i guess because system wants to clear some memory After your Step4 your backStack looks like below
Your back stack after method 4 is like this
SecondActivity Step 4
MainActivity Step 3
SecondActivity Step 2
MainActivity Step 1
According to developer website
onDestroy methods called
The final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
As the system calls the stop method after that the destroy method is called for the activity and it's upto the device when to call the destroy method.
The stop method doesnot delete the memory of the activity on the device but the activity is not working anymore but as soon the destroy method is called all the memory allocation of the activity is destroyed.
Its totally dependent on device & # of running application. If you have a high end device (which has >1GB RAM; you probably will not see getting onDestroyed() called. That is because Android can keep more application running within more memory.
Again you can always force onDestroy() getting called by killing task from TaskManager. Alternatively you can set the developer option "Do not Keep activities" on ICS+ devices. This will always destroy your app whenever you leave it.
The main difference between onStop() and onDestroy() is that onStop() only suspends your Activity (UI & UI thread) but it does not touch your running threads (like network thread, Services, receivers e,g ). So, your app can still work (play music or download something) on background even if onStop() is called.
onDestroy() is called by android system to claim memory space (for new activity invoke or itself) and it will destroy the Activity which sits on the bottom of ActivityStack. You can think onDestroy() as a graceful shutdown request from system. You should stop everything if onDestroyed() called. After this call your every thread will be terminated.
Hope this helps, regards.
I'm trying to make a simple notepad application and I would like to refresh the notes when the New Note activity finishes and the main screen resumes. However I get force close when trying to open the application with this code. If I remove the OnResume thing it doesn't force close. Help?
public class NotePadActivity extends Activity implements View.OnClickListener {
TextView tw;
String data;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tw = (TextView)findViewById(R.id.uusi);
tw.setOnClickListener(this);
Note note = new Note(this);
note.open();
data = note.getData();
note.close();
tw.setText(data);
}
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.uusi:
try {
startActivity(new Intent(PadsterActivity.this, Class.forName("com.test.notepad.NewNote")));
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
Note note = new Note(this);
note.open();
data = note.getData();
note.close();
tw.setText(data);
}
}
The problem is you have two different TextViews called tw see my comments on your code...
public class NotePadActivity extends Activity implements View.OnClickListener {
TextView tw; // This never gets instantiated
...
Another here...
public void onCreate(Bundle savedInstanceState) {
...
// This is instantiated but is local to onCreate(...)
TextView tw = (TextView)findViewById(R.id.uusi);
Then in onResume(...) you attempt to use the instance member tw which is null...
protected void onResume() {
...
tw.setText(data);
Change the line in onCreate to...
tw = (TextView)findViewById(R.id.uusi);
...and it should fix the problem.
BTW, you don't need to duplicate everything in onCreate(...) again in onResume() as onResume() is always called after onCreate(...) when an Activity is created.