Android SavedState - android

I have tried every way possible to use SaveState in a prior post I was instructed to use finish() or use onBackPressed ok that saves the data on the MainActivity but I would like to understand how to use Bundle savedInstanceState below is my code arrangment Please comment what is wrong and offer suggested fixes My goal is to only restore one value in one of the EditText fields?
Yes I have looked at Adroid Developer and numerous other quality sites
public class MainActivity extends AppCompatActivity {
Button btnAdd;
Button brnNext;
EditText ETinput;
EditText ETans;
float X = (float) 10.0;
public final static String EXTRA = "com.dwight.thebigtest.pagetwo.MESSAGE";
public int sVarA;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
savedInstanceState.putInt("sVarA",sVarA);
btnAdd = (Button) findViewById(R.id.btnAdd);
brnNext = (Button) findViewById(R.id.btnNext);
ETans = (EditText) findViewById(R.id.ETans);
ETinput = (EditText) findViewById(R.id.ETinput);
addListenerOnButton_ADD();
}
#Override
protected void onRestoreInstanceState(Bundle InState) {
super.onRestoreInstanceState(InState);
if(InState != null) {
sVarA = InState.getInt("sVarA");
ETans.setText(String.valueOf(sVarA));
}
}
private void addListenerOnButton_ADD(){
btnAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
float Y = Float.valueOf(ETinput.getText().toString().trim());
float Z = Y + X;
ETans.setText(String.valueOf(Z));
}
});
}
public void sendNext(View view) {
Intent intent = new Intent(MainActivity.this,PageTwo.class);
String message = ETans.getText().toString().trim();
intent.putExtra(EXTRA,message);
startActivity(intent);
}
}
This code makes the trip back from the secondActivity
private void addListenerOnButton_Back(){
btnBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(PageTwo.this,MainActivity.class);
startActivity(i);
//onBackPressed();// Less Screen Flash
}
});
}
}

This snippet caught my eye:
Intent i = new Intent(PageTwo.this,MainActivity.class);
startActivity(i);
//onBackPressed();// Less Screen Flash
You're making a new Intent to return to the MainActivity, but instead, it creates a new instance of MainActivity which is then added to the activity stack. When the new MainActivity is created, it has NO savedInstanceState: it's brand new.
onBackPressed and finish are the appropriate ways of finishing the current activity and returning to the previous one.
The purpose of savedInstanceState is to restore the state of an activity when it is destroyed by the system (for instance, due to lack of memory). If you simply return to the previous activity via the back button, savedInstanceState is not used because the activity is still in memory. No need to restore it.
If you enable "Don't keep activities" in your phone/emulator's Developer Options, Android will force-stop activities once abandoned. So when PageTwo is created and shown, since MainActivity is no longer in the foreground, it will be destroyed. This is where the instance state is saved. When you return to the same MainActivity (pressing back), the activity must be recreated using that instance state.
For more information, research about Android's activity lifecycle.

Related

Why do I get a NullPointerException here?

I have my code defined the way below. There are two crucial activities. Activity (1) shows some images in a ViewFlipper. It uses methods to load desired image directly. The onOptionsItemSelected() method fetches data from a menu defined within linked XML layout R.layout.browse. The other method, displaySelectedFlag(), gets a tag parameter passed from a different activity, let's call it activity (2).
Activity (1):
public class BrowserActivity extends AppCompatActivity implements SimpleGestureListener, View.OnClickListener {
public ViewFlipper vFlipper;
(...)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.browse);
vFlipper = (ViewFlipper) findViewById(R.id.viewFlipperBrowser);
(...)
} // onCreate() ends here
// this method below works fine:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
vFlipper.setDisplayedChild(item.getOrder());
return true;
}
// and this one doesn't:
public void displaySelectedFlag(int orderTag) {
vFlipper.setDisplayedChild(orderTag); // crashes here
}
}
Activity (2):
public class ListActivity extends Activity implements View.OnClickListener {
private BrowserActivity browserActivity = new BrowserActivity();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
ImageButton imageA = (ImageButton) findViewById(R.id.img_a);
imageA.setOnClickListener(this);
ImageButton imageB = (ImageButton) findViewById(R.id.img_b);
imageB.setOnClickListener(this);
}
public void displayImageInfo(View view) {
String tagValue = (String) view.getTag();
int tagId = Integer.parseInt(tagValue);
Intent intent = new Intent(this, BrowserActivity.class);
startActivity(intent);
browserActivity.displaySelectedImage(imageId);
}
#Override
public void onClick(View view) {
displayImageInfo(view);
}
}
As I checked, the method onClick() called in activity (2) fetches an ID of an ImageButton and passes it to activity (1). Unfortunately, I get a NullPointerException when calling the ViewFlipper (the line is marked in the code above, activity (1)).
Any idea why it happens?
You cannot reference one Activity from another activity. You must let the Android OS create the Activity object via the call to "startActivity". Allocating a local variable as an instance of an Activity doesn't actually mean anything (like your instantiation of the BrowserActivity). Apoorv's comment links to a decent article on the subject.
If you want to pass data from one Activity to another, you need to pass extras within the Intent's bundle. This post goes into detail: https://stackoverflow.com/a/819427/504252

edit text saving status in android

i did a lot of trials before coming here, i need that user find the same values entered in
an activity when he returns to , i did this code but it is not working :
public class ActivityUn extends Activity {
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putString("arm_1", rm_1ts);
savedInstanceState.putString("arm_2", rm_2ts);
super.onSaveInstanceState(savedInstanceState);
}
public void ajouter(View v) {
db.open();
long id = db.insertMENAGE(rm_1ts,rm_2ts); }
EditText rm_1;
EditText rm_2;
String rm_1ts = "";
String rm_2ts = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_un);
rm_1 = (EditText)findViewById(R.id.rm_1);
rm_2 = (EditText)findViewById(R.id.rm_2);
if (savedInstanceState != null) {
// Restore value of members from saved state
rm_1ts = savedInstanceState.getString("arm_1");
rm_2ts = savedInstanceState.getString("arm_2");
rm_1.setText(rm_1ts);
rm_2.setText(rm_2ts);
}
Button bton = (Button)findViewById(R.id.ajoutUn);
bton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rm_1ts = rm_1.getText().toString();
rm_2ts = rm_2.getText().toString();
ajouter(v);
}
});
The problem is that onSaveInstanceState is only called when your Activity is killed via System to free memory or a 3rd party app. But when you press a back button in an Activity it simply is equivalent to finish(). In this case onSaveInstanceState is not called. So if you want to store data every time your Activity is created just store the values in a SharedPreference. You can store the values either in onStop or onPause method depending on your needs.
Here you can learn more about SharedPrefence and other types of storage options.
For the sake of simplicity, you could store the value in the SharedPreferences.
getSharedPreferences().edit().putString("myEditText", yourValue).commit();
That's it.
Try restoring the state in onStart or onResume instead of onCreate. onCreate is only called if the activity needs to be recreated after it is destroyed. Often the activity will be retained in the background in a stopped state, and won't call onCreate when it comes back.
Anywhere in your file, put:
#Override
public void onResume() {
super.onResume();
//Your code here
}

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.

Activity instance remains in the memory after onDestroy()

I know that this topic has been already beaten enough, but I still don't understand completely if Android System has fine behavior in following case:
I created small app consists of two classes, here is the code:
Main.java
public class Main extends Activity {
private Button bv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bv = (Button) findViewById(R.id.hello_txt);
bv.setOnClickListener(
new OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(Main.this, Main2.class);
startActivity(i);
}
}
);
}
}
Main2.java
public class Main2 extends Activity {
private TextView countOfActivities;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
countOfActivities = new TextView(this);
setContentView(countOfActivities);
countOfActivities.setText("Count of Activities: " + getInstanceCount());
}
}
When I clicked on the button from first activity several times, I get that even after pressing BACK button that should call second Activity's onDestroy() it's instance remains in the memmory.
Only after creating about 35 instances next click let me know, that GC cleared the memmory.
I just want to completely be sure that it is normal system's behavior.
Following pictures from Emulator and LogCat
Button clicked 10 times
LogCat output after clicked
Yes, the system works fine.
When you press the back button, your activity is removed from the activity stack.
onDestroy() may have been called, this doesn't mean that the instance was actually unallocated from the memory.

Android: Button action not being called

I'm trying to make an app where you start at a menu, click a button and are brought to a list of items (which I later hope to make clickable). But I can't seem to make it call my next activity. Can anyone help?
Your main class / activity:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Menu Button
Button startNewActivity = (Button)findViewById(R.id.startnew);
startNewActivity.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent newActivityIntent = new Intent(YOUR-CLASS-NAME.this,NewActivity.class);
startActivity(newActivityIntent);
}
});
Your NewActivity Class:
public class NewActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new);
}
}
Is the question "How do I call the next activity" ?
If so, it's pretty easy - Assuming the Activity you want to call is "SomeActivity", call this:
Intent someActivity = new Intent(getBaseContext(), SomeActivity.class);
startActivity(someActivity);
There's also a "startActivityForResult" method, if you want data back from the Activity you're calling. For reference, the Activity page of the API Documentation can be found here. Good luck!

Categories

Resources