I have a function time() in my openGLActivity class. The openGLActivity is open by my Main activtiy. I've tried calling super.onPause() then super.onStop(); and i just get errors. This time function is called inside of my GLrenderer class. Can an activity cloe itself after a time limit?
timer(){
t+=1;
if(t==1000){
finish();
}
}
If I didn't misunderstand your question, you can easily do that with handler. This should close the activity. Use it onCreate()
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
OpenGLActivity.this.finish();
}
}, 3000);
Activities in the system are managed as an activity stack. It means that if Activity1 calls Acitivity2 by
startActivity(Intent i)
Activity2 remains alive until you go back since the Activity1.
Related
I have startActivity and HomeScreen activity. HomeScreen activity appears after startActivity. I want to implement double click back to close the application. I tried this code, but after the app is closed, it immediately reopens again or just returns to startActivity.
#Override
public void onBackPressed() {
if (doubleBackToExitPressedOnce) {
super.onBackPressed();
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(this, "Нажмите ещё раз что бы закрыть приложение", Toast.LENGTH_SHORT).show();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
doubleBackToExitPressedOnce = false;
}
}, 2000);
}
If this code is in some child activity (not in the main activity), then try replacing:
super.onBackPressed()
with:
finishAffinity()
Since according to the docs:
The default implementation simply finishes the current activity, but you can override this to do whatever you want.
calling super.onBackPressed() will finish current activity - not the whole application. And probably this is the source of Your bugs, but I cannot know for sure, since You haven't provided us with broader context - more code.
So, on the other hand finishAffinity() might be the solution for You. Docs say:
Finish this activity as well as all activities immediately below it in the current task that have the same affinity.
This should finish all the activities.
Every time my app enters pAUSE stage and enters onresumestage, i am killing my current activity and start new Acitivy. And at the same time in onresume stage, i try to make some button visible. Some how the visibility function never gets updated. Always stays at defualt invisible stage... any help highly appreciated. ..
// code in onresume stage that makes button ready visible and at the same time call refresh function
public void onResume() {
super.onResume();
refresh();
runOnUiThread(new Runnable() {
#Override
public void run() {
ImageButton ready = (ImageButton) findViewById(R.id.ready);
ready.setVisibility(View.VISIBLE);
}
});
}
// thats where i am killing current activity and starting new activity
public void refresh() {
Intent intent = getIntent();
overridePendingTransition(0, 0);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
// MediaPresentationActivity.this.finish();
finish();
recreate();
overridePendingTransition(0, 0);
startActivity(intent);
}
// xml image button set default visibility to invisible
<ImageButton
android:id="#+id/ready"
android:layout_width="90dp"
android:layout_height="90dp"
android:visibility="invisible"
/>
From the best of my knowledge , refreshing activity kill the current activity. Only issue could be onResume function. You should try java Synchronous function. Currently setvisbility for image button is executed before finishing the refresh function . Actually it does set image button to visible, but refresh function will delete it as both run at the same time. so you should try Synchronous function : which allow second function to call ,only after first function is executed completely.
what simply you can do is calling the same activity again like
Intent intent=new Intent(MainActivity.this,MainActivity.class);
startActivity(intent);
finish();
Note: Replace MainActivity with your own class name.
I am making an android app in java in which I need to trigger some database requests whenever an activity is completely destroyed which would probably happen if the user presses the back button or leaves the app itself... But the onDestroy() function in my app is randomly getting triggered even when the user is still on the activity... I guess the probable reason for this is configuration changes but I am not able to figure out a proper solution for this.
Is there a way we could exactly detect when an activity is left by a user avoiding any in-page configuration changes??
The onDestroy() that I am using is this:
#Override
protected void onDestroy() {
/// do smthng
super.onDestroy();
}
Any help would be appreciated!!
Solved:
Thank you for the answer guys... For me onStop() worked out perfectly and it is working in every case whether it might be pressing the back button or exiting the activity or the app itself!!
If you want to check if the user ended the activity, meaning pressed back, do this:
#override
public void onBackPressed(){
//do something before we finish the activity
super.onBackPressed();
}
If you want to check when user, goes to next activity, then resturns to the same activity:
#override
public void onResume(){
//do something when return back to this activity
super.onResume();
}
#override
public void onPause(){
//do something before going to another activity
super.onPause();
}
onDestroy is called when the activity is destroyed or finished and not guaranteed to be called always, don't depend on it
We can check on whether our application is foreground or background based on the activity entering and exiting the foreground by implementing ActivityLifecycleCallbacks.
Good reference : https://medium.com/#iamsadesh/android-how-to-detect-when-app-goes-background-foreground-fd5a4d331f8a
Quoting from the above article,
#Override
public void onActivityStarted(Activity activity) {
if (++activityReferences == 1 && !isActivityChangingConfigurations) {
// App enters foreground
}
}
and,
#Override
public void onActivityStopped(Activity activity) {
isActivityChangingConfigurations = activity.isChangingConfigurations();
if (--activityReferences == 0 && !isActivityChangingConfigurations) {
// App enters background
}
}
by which we can make sure that our app is in foreground or not. Here you always have the control of what activity is in foreground based on which you can check and execute the logic.
I've got two activities, A and B. Activity B can be opened by pressing a button in Activity A.
In activity B I have an integer variable which I would like to keep for when I return to activity B from A. My problem is when I press the back button to go from B to A the activity is destroyed.
I have overwritten the onBackPressed method to:
#Override
public void onBackPressed(){
Intent i = new Intent(this, Game.class);
startActivity(i);
}
I can see from my logs that activity B is in the state onStop() after back button is pressed, however, onRestart() is not being called so the activity must be getting killed for memory reasons.
I have read answers to other posts suggesting I use onSaveInstanceState() but when I try to access the bundle in onCreate() the bundle is null. Method onRestoreInstanceState() does not get called.
protected void onSaveInstanceState(Bundle savedInstanceState){
Log.i(LOG, "instance saving");
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("score", userScore);
}
I have also tried SharedPreferences but this is not useful because I do not want my data to persist when the activity/application is intentionally destroyed.
I think your problem is in understanding the whole Task ecosystem. When you press back button you pop out your activity from the Task, because of that it is destroyed and onDestroyed() is called. To sum-up I think you are just getting every time a brand new activity. onSaveInstanceState() isn't called because activity is killed by user, not by the OS.
Take a deeper look at this developer tutorial.
Also I think those two must be helpful : me and me!
you can store variables in the app class https://developer.android.com/reference/android/app/Application.html or you can make your own singleton class for this
https://www.tutorialspoint.com/design_pattern/singleton_pattern.htm
Starting a Activity - A on onBackPressed will definitely kill the current Activity - B. Instead of starting Activity again just call onBackPressed in Activity - B and add a stage called onResume() which is called when you resume back to Activity B from A
Remove this:
#Override
public void onBackPressed(){
Intent i = new Intent(this, Game.class);
startActivity(i);
}
With this:
#Override
public void onBackPressed(){
super.onBackPressed();
}
When you coming back from A to B, in B #Override stage onResume() and in this you can save the value while coming back from Activity A.
Add this in Activity B:
#Override
protected void onResume() {
super.onResume();
// save values here for resume
}
Look the Activity Life Cycle:
I've been playing around with an app I created.
Activity A(1st Activity) has a button that executes an AsyncTask. This AsyncTask's doInBackground() performs calculations on selected values in Activity A, and its onPostExecute() starts Activity B.
I click the button, then before Activity B can be started I press back to destroy Activity A.
The app closes, then relaunches with Activity B populated with calculations from my AsyncTask.
this awesome blog explains memory leaks with Threads when the screen is rotated, and I'm applying those lessons here with my AsyncTask and back button press. However, I'm still a little confused.
Pressing back on an Activity destroys it.
My asynctask is running on an activity that was destroyed, should throw a NPE since it's accessing list elements inside that activity.
But it didn't. What does destroyed really mean then? I thought it meant that the Activity A reference and its view hierarchy would be set to null to allow the garbage collector to sweep it up sometime and recycle the memory. The blog states it didn't, hence the memory leak.
So wait, Activity A didn't get destroyed? But I saw it disappear...
This is a conceptual question rather than a code question so far, but as requested:
private class MyAsyncTask extends AsyncTask<ArrayList<Train>, Void, Void> {
protected void onPreExecute() {
// Runs on the UI thread before doInBackground
spinWait.setVisibility(ProgressBar.VISIBLE);
waitMsg.setText("Calculating Schedules....");
spinWait.bringToFront();
waitMsg.bringToFront();
}
#Override
protected Void doInBackground(ArrayList<Train>... lolTrains) {
try {
calcSchedules(lolTrains[0]);
} catch (Exception e) {
Log.d("DEBUG", "Calculating schedules failed, " + e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(Void v) {
// This method is executed in the UIThread
spinWait.setVisibility(View.GONE);
waitMsg.setVisibility(View.GONE);
// if schedules is empty, show error dialog
if (schedules.size() == 0) {
// show msg, etc
} else {
Intent i = new Intent(getBaseContext(), ResultsActivity.class);
i.putExtra("results", schedules);
startActivity(i);
}
}
}
public void MethodInActivityA(View v) {
new MyAsyncTask().execute(memberVarInActivityA);
}
When you destroyed your activity, you did not destroy you AsyncTask (which is basically kind of a Thread), to do that try
asyncTask.cancel(true);
on your onDestroy(); method
hope this helps
On your onPostExecute(), When start new activity call finsih() followed by startActivity(i). This finish() internally call onDestroy. Here you need to clear Asynctask manually because Asynctask is inner class of your Activity. Even activity was destroyed this inner class holds the reference of activity. You need manually clear the reference by asyncTask.cancel().