Anytime i change my in-app-settings (with shared preferences) i have to use the back button and go back into the activity for the changes to take effect. I'd like them to take effect immediately. I tried to use
protected void onResume(){
super.onResume();
}
but it doesn't work. What am i doing wrong? My settings activity is called by menu inflater and finished when i click on the save button.
Here are some things to look out for:
You're writing the new settings to the same file as the one being used, and not a different one
Most people use local variables to store settings on a run to run basis. Make sure you update all of these after changing the settings. A good way to do this is to have a seperate method like updateUserChoices(), and have all the code like boolean sound = settings.getBoolean(); in it. Then simply call this method at the beginning, and after you update the settings.
Related
After user inputs parameters in MainActivity for my app (shown below), he taps Search, which calls MatchesActivity, which generates output on a new screen (shown further below), which is exited via tapping back.
But with MatchesActivity active, every time the device is rotated, Search is again executed because the Activity restarts. In the screenshot below, I rotated device from vertical to horizontal to vertical to horizontal back to vertical.
It looks silly.
The output is generated in MatchesActivity that is invoked in onCreate in MainActivity like so:
Intent matchesIntent;
matchesIntent = new Intent(MainActivity.this, MatchesActivity.class);
startActivity(matchesIntent);
Here's the essence of onCreate for MatchesActivity:
#Override protected void onCreate(Bundle savedInstanceState)
{
MainActivity.dbc.setDbProcesslistener(this); // to know txaMatches has been defined
MainActivity.dbc.findDBMatches(); // generate output
}
I did research. I found some complicated ways of preventing an activity from restarting when the device is rotated. For example .
I'm hoping for a simpler solution. Any ideas?
As you have found, one option is to prevent the activity from being recreated on configuration changes all together. This is not always the best option, as this will prevent other things depending on the configuration from being recreated/reloaded too (e.g. resources overridden with the "-land" qualifier).
Another option is to cache the result of the DB search somehow. This could be done by adding a wrapper around your database that memorizes the term and results of the last search. Another way to cache the results would be to use a fragment, and reuse that fragment across activity recreations. Whether a fragment is recreated along with its activity is controlled by this method:
http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance(boolean).
My solution was simple.
Introduce boolean variable outputIsShowing, set it to true in onCreate as MatchesActivity terminates, set it for false when onCreate or onResume are executed in MainActivity (i.e., when MatchesActivity terminates), and return immediately in onCreate for MatchesActivity if outputIsShowing is true.
So if MatchesActivity is active when device is rotated, outputIsShowing will be true, so don't execute again.
It may not be best practice, but I've extensively tested it under normal conditions and am happy enough so far. Not sure if anything is lurking out there as a "gotcha".
I plan to go back and study the suggestions made so far since the more general situation is definitely important. And I will have to do so if someone finds fault with what I've done.
#Override protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// usual details prior to asking for matches
if(outputIsShowing)
return;
MainActivity.dbc.setDbProcesslistener(this); // to know matches was defined
MainActivity.dbc.findDBMatches();
outputIsShowing = true;
}
* EDIT *
Strangely, after embedding TextView txaMatches in a ScrollView to accomplish smooth, accelerated scrolling, I had to remove the references to outputIsShowing in order to see output after two device orientation changes.
And now, maybe I'll submit another question to address the fact that, very infrequently after screensaver forces waking the device, the output does NOT show if that is where the focus was when screensaver became active. Tapping 'back' to get to user input screen and then immediately tapping Search restores all to normal until about 100 (give or take) screensaver instances later, the output is again missing.
Such a bug makes me think I ought to follow the advice above.
If I do, or when I figure out the problem, I'll edit this again.
I'm new to android, and i don't know how to make an app that if you set things inside it it will save your progress once you close it.
for example, when use input's something into an EditText, like in a to-do list app, i want all the data of the app to be saved even after shutdown.
Thanks.
Use SharedPreferences http://developer.android.com/reference/android/content/SharedPreferences.html
Obtain them using getDefaultSharedPreferences(Context context)
I need to make sure that the options menu has been created before i run a certain code that accesses one of the menu items. Is there a callback for that or how can i implement one?
Is there any guaranties that the menu has been created on the activity's onResume()?
You cannot use onResume for this.
In fact this is the call order when your app is launched :
onResume()
onCreateOptionMenu
onPrepareOptionsMenu
As you can see onCreateOptionsMenu is called AFTER onResume
(you can verify this yourself by writing to the console in the overriden methods).
Also notice that onPrepareOptionsMenu is called at least once - when your app is starting, even though the menu is at that time not shown to the user.
Now, you do not write in great detail about what you are trying to do, but if what you want to do is this "run a certain code that accesses one of the menu items", then you can use onPrepareOptionsMenu as it is called AFTER onCreateOptionsMenu and it also called whenever your app comes to the foreground - i.e. after onResume. Depending on whether this code needs to run once or everytime you can use a boolean flag inside that method (or store it in the Preferences or similiar persistent data if it is only once ever).
There are no other callback hooks mentioned in the documentation and I have never had the need for others, as onPrepareOptionsMenu should be enough to do the job. If you feel this is not the case, you need to be more specific in your answer and provide code for your specific usecase.
But as I said before, no other callbacks are mentioned in the documentation.
It is not a callback for after onCreateOptionsMenu is done, but onPrepareOptionsMenu can be used if you want to modify the menu before it is displayed to make modifications. This would only be called after onCreateOptionsMenu (if Android is behaving, which is should).
http://developer.android.com/reference/android/app/Activity.html#onPrepareOptionsMenu(android.view.Menu)
See the Activity documentation on this:
http://developer.android.com/reference/android/app/Activity.html#onCreateOptionsMenu(android.view.Menu)
I am trying to figure out how, when a user lands on my activity screen, it is "reloaded" as if it were being loaded for the first time.
I don't want my user hitting the back arrow and coming back to my activity with old information.
As it is now, when a user "comes back" to my page, the database list isn't being repopulated, and information they typed into EditText fields remains there.
I want the page, everytime the user comes to it, to be like it's their first time there.
Have you ever tried using recreate() in your current activity? Try using it after your new values are populated.
Or you can just put everything that's in the onCreate() on the onResume. A bit ugly but it works.
I have to disagree with Kartik on this, as I understand, android:noHistory='true' will remove activity from application stack. So when user hits back, user will not be able to see the activity at all.
About activity not retaining its value, I would not recommend you this, as user expects that all values would be retained when back is hit, unless there is some specific requirement that you are trying to meet.
So I guess solution to your problem is, as others have suggested do your initialization on views in onResume(). But just doing this may not be sufficient, as views like EditText will by default cache the values anyways. So you might have to manually clear those in your on onResume(). Will keep looking to find any 'perfect' solution if any to this problem.
I had solving similar problem like yours and I solve it whit lunch mode.
I think the best is to take a look of this set the lunch mode in single instance and then
in you onCreate and onResume you can code to refresh you view just the way you want it.
copy requred code into onResume() from onCreate() method
I am writing a 3d live wallpaper for android using the famous GLSurfaceView wrapper (http://www.rbgrn.net/content/354-glsurfaceview-adapted-3d-live-wallpapers)
When i open the preference screen to change wallpaper settings, the settings are displayed as transparent over my wallpaper preview. This is good because it lets me preview the settings changes I make. This works great, except for one problem: The live wallpaper is paused as long as the settings are on top of it!
How can i avoid my wallpaper pausing?
I came up with a workaround which could be useful, depending on how your wallpaper functions...
In my settings activity, whenever the user makes a change (e.g. moves a slider, checks a checkbox), I broadcast an Intent with the relevant settings information.
In the live wallpaper's onCreate method, I dynamically register a BroadcastReceiver to receive these settings events. I unregister this receiver in onDestroy.
When receiving a settings broadcast, I make the wallpaper draw a single frame with the new settings. As the settings activity is transparent, this immediately gives the user an idea of what the wallpaper will look like with the chosen settings.
Similarly, using this approach, you could schedule the wallpaper to animate for a few seconds after a settings change — or whatever is appropriate for your implementation.
I found this to be kinda annoying as well. I averted the issue altogether by simply calling finish() in my settings activity whenever a change is made. This allows for an instant, full preview of the wallpaper for the user. It only takes a click to go back into the settings to make another change and it makes for a rather nice user experience.
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
finish();
}
I used this in my line of wallpapers. Here is an example: