Super should be called at the end of the method - android

#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
((CustomApplication) getApplication()).detach(this);
}
While generating PMD report, i got this Error: Super should be called at the end of the method. Normally you would eventually keep the super method at the top(First Statement) so that its parent class is first called initialized.

Normally you would eventually keep the super method at the top(First
Statement) so that its parent class is first called initialized.
The following code snippet shows you how Activity#onSaveInstanceState(Bundle outState) looks like. You can see that it only saves the Bundle you passed in as an argument by calling super.onSaveInstanceState(outState);. So it would make no sense to call the super method before actually saving something inside the Bundle.
protected void onSaveInstanceState(Bundle outState) {
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
getApplication().dispatchActivitySaveInstanceState(this, outState);
}

According to this SO, it doesn't matter where you call it as long as the key do not collide. They should be equivalent.
So long as your keys do not collide (e.g., ID being the same as something Android uses internally), the two are identical.
But with that being said, Google's documentation about The Activity's Lifecycle shows adding this at the end. I would still follow that though:
// invoked when the activity may be temporarily destroyed, save the instance state here
#Override
public void onSaveInstanceState(Bundle outState) {
out.putString(GAME_STATE_KEY, mGameState);
out.putString(TEXT_VIEW_KEY, mTextView.getText());
// call superclass to save any view hierarchy
super.onSaveInstanceState(out);
}

Related

Deleting values when the user closes the application

So in my application I am using SharedPreferences to save fragment state. But I would like to delete those entries inside the SharedPreferences once the user steps outside of the application. I tried the following:
In my main class:
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
if(isFinishing() == true)
{
SM.removePreferences();
}
}
where SM is an instance of a helper class I created. removerPreferences does the following:
public void removePreferences(){
editor.clear();
editor.commit();
}
But I noticed that this was never executed. With the log, I did see that the app goes inside the isFinishing() if statement, but the method is never executed. I also did try the onDestroy(), but the method never got called.
Can someone help me on this ?
use onstop override to do that
like this:
#Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
if(isFinishing() == true)
{
SM.removePreferences();
}
}
Don't save your Fragment's instance state in SharedPreferences, but in the Bundle that is meant to do that. You can access it like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if ((savedInstanceState != null) {
// get your values, for example:
mID = savedInstanceState.getInt("ID");
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// put your values, for example:
outState.putInt("ID", mID);
}
This way you don't have to manage the values yourself.
If you have custom Objects, you can make them implement Parcelable.
In contrast, SharedPreferences are meant to save values that should persist even after the application closes, i.e.: preferences.
The better location to do that is onDestroy() without the if statement.
however, you can read from Android documentation about onDestroy() that:
There are situations where the system will simply kill the activity's hosting process without calling this method (or any others) in it, so it should not be used to do things that are intended to remain around after the process goes away.
So, in my opinion, if you don't want data remains after activity ends, you should use a class to hold it.
I think that what you're looking for can be achieved using onSaveInstanceState mechanism.
Nonetheless, I'll try answering your specific question while assuming that by saying that "the method is never implemented" you mean that the if statement value is always false and that your method doesn't get called.
isFinishing() returns true only when you called finish() on the Activity or if someone else has requested that it will be finished.
If you just click on the home button, you will get isFinishing() == false, thus your method doesn't gets called. So make sure you're actually finishing the Activity and not just pausing it.
Anyways, the best way to find out what's the problem is to use the debugger.

Where is a Bundle variable saved in Activity?

public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putInt("x", x);
}
When I save a Bundle, Where is the Bundle variable exactly saved? I can't find it anywhere
In addition to android reference, you can read the source code to understand what has happened here.
protected void onSaveInstanceState(Bundle outState) {
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
getApplication().dispatchActivitySaveInstanceState(this, outState);
}
In the source code, it's clear to see the state will be managed by Application. When the Activity is destroyed, the Application can help save relevant states. But, if you ever met this situation that Application was killed, you would find all states were lost. So, I think all states are kept in memory, not file like preference.
Well, I don't think you will find it and I don't expect to be referenced directly somewhere.
However its content will be available in onCreate(savedInstanceState) when the activity is recreated. Taken from its documentation: savedInstanceState: If the activity is being re-initialized after previously being shut down then this Bundle contains the data it most recently supplied in onSaveInstanceState(Bundle). Note: Otherwise it is null
Another place to look for its content is onRestoreInstanceState(savedInstanceState)
i am not sure I think you must set the int,string or whatever you want
so as to save it into int
Let me show you an
EXAMPLE
public void onSaveInstanceState(Bundle state){
super.onSaveInstanceState(state);
Int i = 1;
state.putInt("s",i);
}

onResume() is not called in physical device instead onCreate() is called

Iam little bit amazed with this.I have an onResume() in my activity.Its called and works well in my emulator, but in a physical device samsung galaxy note for specific with jellybean installed,its not called.Instead onCreate() is called all the time.Why this happens?
public void onResume(){
super.onResume();
if(firsttime){
try {
Toast.makeText(getApplicationContext(), "Resuming Activity",Toast.LENGTH_LONG).show();
addReminder();
} catch(Exception exception) {
exception.printStackTrace();
}
} else {
firsttime=true;
}
}
This is my code.firsttime is a static boolean variable.It is used to prevent onResume() being called when app is started for the first time
Considering your current scenario, you should save variable in preferences instead of relying on activities lifecycle since lifecycle depends on many things.
Using static variable for this scenario is bad choice in general.I think this should solve your problem.
Try to print something inside the onResume and check it in LogCat.... the code inside onResume may be causing this.
or else can you elaborate your question?
I think here is what happens,
when your app not the Top app, the activity manager actually destroy the activity, it only called
public void onSaveInstanceState(Bundle savedInstanceState)
no
onStop
called, so no
noResume
will be called.
The correct to do this is, when put all states of this activity when
public void onSaveInstanceState(Bundle savedInstanceState)
called.
and in your onCreate() function, do such thing
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // Always call the superclass first
// Check whether we're recreating a previously destroyed instance
if (savedInstanceState != null) {
// Restore value of members from saved state
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
} else {
// Probably initialize members with default values for a new instance
}
...
}
to check if you have some saved state.
Most code was copy from android developer site:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html

Fragment saveInstanceState is coming as null after orientation change

I have an activity with action bar tab. Each tab contain a fragment. Now when I rotate my device, bundle in my corresponding fragment is coming as null. This is taken care when I using device post android 3.2, but it is happening when device is Andoird3.0. I am having a headache after working on this issue. I crossed check various link on SO, but no help. Although I have given enough details, still will provide some code snippet as at various cases user ask for code snippet.
In my fragment class I am storing this value
#Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putBoolean("textboxVisible", true);
}
this is storing one boolean variable which it retrived as below.
/**
* Function called after activity is created. Use this
* method to restore the previous state of the fragment
*/
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null)
{
//restore the state of the text box
boolean textboxVisible = savedInstanceState.getBoolean("textboxVisible");
if (textboxVisible)
{
//do some stuff
}
}
}
but after rotation savedInstanceState is coming as null.
I don't what is going wrong. I have read in some document that below 3.2 the onCreateView() of
fragment is not called with bundle value. But to deal with this. Any help will be appreciated.
if you use setRetainInstance(true) the savedInstance bundle is always gonna be null after orientation changed. SO you cannot really save something with it, but what you can do if you need to save something, is to put it in a data member of the fragment, because setRetainInstance(true) preserves the fragment and doesn't destroy it, so after the device was rotated you gonna have the same values.
Try to get the savedInstanceState in onCreate of the Fragment.
Like
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
if (savedInstanceState != null) {
// IT MUST NOT BE NULL HERE
}
}
Please try... i hope it will work

Method to override when layout is destroyed in Android

I have a custom component which extends LinearLayout, I need to execute certain statements when Layout is destroyed or removed. (or about to be removed)
One way is to check for onPause() or onDestroy() of an activity and call methods of the custom component. But I want to remove that overhead from the activity.
So that custom component itself can handle when layout is detached. But I dint find the suitable method to override (to detect the event) when layout is removed. Is there a way to handle this, or we need to use onPause() and onResume() method of activity ?
I had success overriding the onAttachedToWindow() and onDetachedFromWindow() methods:
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
// View is now attached
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
// View is now detached, and about to be destroyed
}
You can have your custom view listen to its own eventss. I suggest using View.OnAttachStateChangeListener and listening to onDetach event.
#Override
void onViewDetachedFromWindow(View v) {
doCleanup();
}
It is dangerous to rely on the "destruction" of a layout to execute statements, as you're not directly in control of when that happens. The accepted way and good practice is to use the activity's lifecycle for that.
But if you really want to tie your component to that lifecycle, I suggest your component implements an interface (something like Removable), and do something like that in your base activity classe (that all your activities extend):
protected Set<Removable> myRemovableItems = new HashSet<Removable>();
#Override
public void onPause() {
super.onPause();
for (Removable removable : myRemovableItems) {
removable.remove();
}
}
The interface:
public interface Removable {
void remove();
}
Then each time you add one of your custom component from an activity, you add the component to the internal set of Removable of the activity, and its remove method will be automatically called each time the activity is paused.
That would allow you to specify what to do when onPause is called within the component itself. But it wouldn't ensure it's automatically called, for that you'll have to do it in the activity.
Note: you can use onStop instead of onPause depending on when you want the removal to occur.

Categories

Resources