Refresh activity without re-opening it? - java

I implemented a button in my app that clears all sharedpreferences using this code:
context.getSharedPreferences("bifrostPrefs", 0).edit().clear().commit();
Now the problem is that whenever I use the button, I then need to exit the activity and re-open it to see results. I tried solving this by simply making the button re-open the activity with this code:
Intent reOpen = new Intent (Bifrost.this, Bifrost.class);
startActivity(reOpen);
My idea seemed smart until I noticed that if I re-open the activity, I then need to press the back button twice to get back to main activity. So I did some reserach and found this code:
finish();
startActivity(getIntent());
This now works fine, the activity gets refreshed and then I only need to click the back button once. But is there another way to refresh activity without it "flashing" in and out? As you know, everytime you open a new activity, it flashes in and out so the app lags for a second. Is there a way to refresh an activity by bypassing this?

Well, it would be better to update the content of the activity, but if it's too complicated you can override the default animation with this method :
finish();
overridePendingTransition( 0, 0);
startActivity(getIntent());
overridePendingTransition( 0, 0);

You can add the flag Intent.FLAG_ACTIVITY_NO_ANIMATION (link) to your reOpen intent to eleminate all animations. But as stated from the other answer better refresh the data inside you Activity.

do you have some views that may change their value/size based on values from your shared preferences? if yes, create a method that init the views and call that methon on onCreate() method and in onClick() method.

Related

Confusion between onPause() onStop() onResume()

I am developing an Android app in which I want to check if the user has minimized the application or just come from another activity.
In detail, if the user have started another app, went to the home screen or locked the screen, I want to show the activity where the user will enter the password to access the app. But where or how to check this exactly?
https://developer.android.com/guide/components/activities/activity-lifecycle.html
I was trying onResume() but according to documentation onResume() can be fired if the user’s navigating to another activity and coming back.
I'm not very clear on what you are trying to achieve.
The life cycle diagram is quite clear if you are wondering which lifecycle method it would hit when something happens.
Basically, it's the same to minimise the app and go to another activity. But if you are referring to coming from another activity in your own app, you can distinguish your own activity by adding extra information to the intent you use.
Basically, it's like this:
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra(key,value);
startActivity(intent);
And in your SecondActivity, you can always retrieve that data like this:
Bundle bundle = getIntent().getExtras();
if ( bundle != null && bundle.containsKey(key) ) {
value = bundle.getInt(key); // not nessecarily getInt(), you should use according to your value type
// use the value to tell if it is from your own app
} else {
// it is not from your own app
}
You can use this mechanism combined with the lifecycle methods. For example, if you use the latter code in your onCreate() method, then whenever the Activity is created, if will check who creates it, which sounds like your what you might want.
As soon as your activity becomes visible it will call OnStart() and as soon as it is ready for the interaction(such as touch ,click etc event). it calls onResume, at this stage your app is running and it is completely in foreground. When your activity start another activity or a dialog box then it calls onPause it means activity is visible but user can not interact with the Activity UI. in case we start another Activity which completely hides the previous activity then its onStop method is called
onPause: Called when another activity comes into the foreground.
onStop: Called when that other activity is completely visible.
onResume: Called when your activity is navigated back to from the onPause state.
Maybe your app was already in the onStop state, so then it would call onRestart.

how to make the appliction exit when pressing back button in the main activity?

In my application when i click the back button it passes through all the activities that i open them previously , i used the public void onBackPressed() method to make the back button back to the activity that i want as follow
public void onBackPressed()
{
startActivity(new Intent("com.MyDiet.Main"));
Tracker.this.finish();
}
is that true and safe way to code the back button ? how i can prevent the application from passing through all the previous opened activities when the back button is pressed ? and how i can make the application exit when i click the back button in the main activity?
In your application, and in ALL android applications, unless it's critical not to pass through unneeded steps (such as login if you're already logged in), it's VERY important not to override Android standard behaviour. Users normally complain about Android apps not having a common behaviour or style guideline.
Anyway, yeah, you can just override onBackPressed on all your activities and do whatever you want. But just don't.
This approach isn't good, because you're polluting the activity stack of your application
Example:
current stack: MainAct -> Act2 -> Act3 (we're in activity 3)
With your code above, when you press back, the stack now looks as follows:
MainAct -> Act2 -> MainAct
Because you ended Act3 and launched a NEW main activity, which may be not what you wanted.
To achieve what you want (Get back to main when the current activity is over) you need to work on the intermediate activities: In the example above, when from Act2 you call startActivity("Act3"), you should call "this.finish()". Therefore you don't have to override "onBackPressed()" of activity 3: simply the default value will terminate Act3 and the next activity in the stack will be MainAct
MainAct -> A2 (A2 launches A3 and then calls this.finish())
MainAct -> A3 (user now press back)
MainAct (the mainactivity is now on top)
To summarize, you don't have to override onBackPressed, you just have to correctly manage the lifecycle of the activity between the main one and the current one.
Generally speaking it's not recommended to make things work like user doesn't expect and that is considered as very bad practice. That's why it is not good to start activity from overriden onBackPressed().
When user press back by default activity will finish and one from back stack will be displayed. You as developer will (by writing code) decide which one is that. You can do it this way but later (or for somebody else) it will be a bit messy and difficult to find this unusual place for code which is starting other activity.
So..It would be useful to read about activity lifecycle and back stack to get impression how it works and understand terminology better.
If you want one of your activity not to stay on back stack you can add in manifest file file android:noHistory="true" for that activity.
Same thing you can achieve from code by adding appropriate flag to intent when you start activity: Intent.FLAG_ACTIVITY_NO_HISTORY
When user "go away" from ActivityOne (started using intent or defined in manifest like described), to new ActivityTwo and then press back, it will not go to ActivityOne because it will not be on back stack. Using this you can precisely control navigation through your activities.
More flags are available for use, but I guess this is what you wanted to achieve.
Hope you will find my answer useful. Cheers..
You can use a lot of tricks to exit your complet application for my part i use this start a intent and then from the androidmanifest i choose the category to home and than close the current activity such would be your mainactivity !
public void onBackPressed() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}

Is it possible to force Activities to get re-drawn when the back key is used?

I understand the concept of the back-stack, so I'm pretty sure this isn't possible but thought I'd ask anyway.
If it isn't, then what is the approach to simulate this behavior? For instance, I have an Activity "A1" that starts another Activity "A2". "A2" alters the content that "A1" shows. When the back button is pressed, the old "A1" is displayed with the old content. Whenever "A1" is called again then the new "A1" will show the new content.
How do developers get around this issue?
When a user press the back-button the A1 activity comes back to the foreground. This will not trigger the onCreate() so you can't use that but if you look at the Activity Lifecycle the onResume() method will be called.
So if you move the displaying of the content in activity A1 from the onCreate() to the onResume() method it should work fine in both situations, when the activity is started and when you return to the activity using the back-button.
Check the Activity Lifecycle. When an activity is made visible it will go through onStart and then onResume when it gains focus. You can load new content at one of these points instead of in onCreate if you would like to update whenever the user navigates there.

Android - Show last viewed Activity When press (Home Button-->App Shortcut)

I came to do the eternal question, which so far have not found a solution, I searched on the internet the same problem but found a final solution to this problem.
when I have 2 activities open and I pull the 'Home Button' and then press the shortcut for my application, it shows me again the first activity (the launcher activity), and then to return to the activity that was displayed, I have to press the back button.
what is the solution to this problem?
I want to press the shortcut of my application (after having left my application by pressing the Home Button) show me the last activity was displayed, instead it shows me the first activity (activity launcher).
Thanks in advance.
That is the expected behavior. The launcher will launch the Activity with the filter android.intent.action.MAIN.
There are ways to work around it, though. A very simple one is to have a boolean flag mRunning that you will set to true upon launch. If true, then on the onStart() method you start an intent to launch your second Activity; if false, then go on with setContentView().
If you have several activities to go back to, then a feasible approach is to save the current activity in SharedPreferences and launch it the same way.
Alternatively, your main Activity may be just an entry Activity whose only job is to start the last Activity used.
EDIT: I found this duplicate question: How to make an android app return to the last open activity when relaunched? that has a much better ansewr than mine.
Your application is still running in the background when you press the home button. finish() the activity when you press the Home button if you want to go back.
Depending on whether or not your main activity is ever launched by another activity, or only the application icon, you can use a much simpler solution. If your main activity is only launched by the application icon, you can use isTaskRoot() to check if your main activity is being launched as a fresh start to the application, or if the user is returning and the main activity is being laid on top of other activities that you wish to display instead.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (! isTaskRoot()) {
finish();
} else {
...
}
}
You can use startActivityForResult replace for startActivity when you want to open another Activity.

Why does Android only show the last Activity when using a for-loop?

Perhaps I'm not used to the Android development, but when I look, I expect everything to be done in order. When one activity finishes, the next starts. However, it seems that my code doesn't work that way. Take the following code for example:
for (int i = 0; i < 3; i++){
Intent myIntent = new Intent(Game.this.getBaseContext(), NextScreen.class);
myIntent.putExtra("something", i);
myIntent.putExtra("Opp", oppList.get(i).toString());
startActivityForResult(myIntent, 0);
}
It doesn't display activity one, wait for you to do what you do in that screen, then come back for the second activity. It immediately displays the third activity. If I click on the back button on my android emulator, it will show me activity two... and if I click back again, it will show me activity one... so it just kind of rapid-fires these activities onto the screen without waiting for you to do what you do in these activities. I'm sure I'm not the first person that's wanted to do something like this. Any idea what I'm doing wrong? How do you work around this situation?
Activities execute asynchronously. One way to serialize this is to chain the activites in your onActivityResult method. Pass to each (sub)activity an activity number, starting with 0 and have the sub-activity return it as part of the result. Your onActivityResult logic can deal with the response, then examine the activity number and fire the next activity (if there is one).
I don't believe you can queue up pages like this in 1 handy function. You'd be better off having a function nextPage which takes the current activity have moves the user to the next activity. This could be called everytime the user is ready to proceed to the next page (triggered by a button press or something).
Or just start the next activity on the button press directly

Categories

Resources