I am trying to modify my firebase database when my app is destroyed, that means when I remove the app from the list of recent running app or when I click on Home button ,but I don't know how to do this, I tried to do that in onDestroy() method of every activity but it doesn't work.
This is my onDestroy() method :
#Override
protected void onDestroy() {
super.onDestroy();
FirebaseDatabase.getInstance().getReference().child("users").child(encodeEmail(mAuth.getCurrentUser().getEmail())).child("status")
.setValue("destroyed") ;
/*Toast.makeText(ContactsActivity.this,"closing app",Toast.LENGTH_LONG).show();
MyApp app = (MyApp)getApplication() ;
app.setUpBeforeClosing();*/
}
On Destroy Documentation
Do not count on this method being called as a place for saving data! For example, if an activity is editing data in a content provider, those edits should be committed in either onPause() or onSaveInstanceState(Bundle), not here. This method is usually implemented to free resources like threads that are associated with an activity, so that a destroyed activity does not leave such things around while the rest of its application is still running. 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.
Either use OnPause or Use a service to write data.
Add this in manifest
<service
android:name="com.myapp.MyService"
android:stopWithTask="false" />
Now in your MyService service, override method onTaskRemoved. (This will be fired only if stopWithTask is set to false).
public void onTaskRemoved(Intent rootIntent) {
//save data to firebase
//stop service
stopSelf();
}
reference
Do you have BaseActivity or not ?
I think you just forgot to add this line in the right activity.
I suggest you to create BaseAvtivity.java class and extend all your activities from it, and the BaseActivity would extends AppCompatActivity and then override tbe lifecycle methods in BaseActivity and set new value in onDestroy method.
Related
This is a text I have copied and pasted from this training tutorial.
"Because the system retains your Activity instance in system memory when it is stopped, it's possible that you don't need to implement the onStop() and onRestart() (or even onStart() methods at all. For most activities that are relatively simple, the activity will stop and restart just fine and you might only need to use onPause() to pause ongoing actions and disconnect from system resources."
I don't understand it. Because to the best of my knowledge, an activity is only stopped by calling onStop() and is only started by calling onStart(). How can an activity start at all without an onStart method.
Do you people understand what they mean in this paragraph?
I think they are confusing you with the word "stop" which appears to have multiple meanings in the paragraph.
I would rephrase it as
Because the system retains your Activity instance in system memory
when it is not in the foreground, it's possible that you don't need
to implement the onStop() and onRestart() (or even onStart() methods
at all. For most activities that are relatively simple, the activity
will suspend and restart just fine and you might only need to use
onPause() to pause ongoing actions and disconnect from system
resources.
The point being is that the App can appear to be stopped, when in actual fact, the system has simply paused it and hidden it from the screen. When the user launches it again, the App doesn't need to start (because it technically hasn't stopped), so it is simply resumed.
When you make an Activity and extend the base class Activity, there is already code in the onStop(), onStart(), and onRestart() methods in the base class.
Your activity simply extends these methods, meaning that you could add more code to them by Overriding them.
So, even though Activities are only started and stopped through those methods, you do not have to explicitly override them in your application. In most cases you won't even have to worry about them: They will be called by the base class from which you are extending.
Please make sure, An Activity starts from onCreate method , then onStart is called by system. If you override onStart method then your overridden method will be also called after onCreate method. If you don't override , then default version of onStart is called.
onStop is called after onPause.
Please check this link , and take a look at Activity life cycle . Your concept will be clear.
Difference between onCreate() and onStart()?
you can use an Activity just fine without - if you need to do something special in onPause() you can override the method:
#Override
public void onPause(){
super.onPause();
// Your magic here!
}
Same goes for onStart(), onStop() etc. You don't need to override the methods but you can if you need to do something specific.
How can I stop my whole App in simple terms? (all activities, services, Threads, etc. simply everything) The life-cycle callbacks (especially onStop() and onDestroy()) should be called.
Google suggests the following possible solution:
kill the process: but this wouldn't call the lifecycle callbacks
and finish(); but this is only for one Activity:
But is it possible to access this method from outside like:
//Getting all activityies, how?
//For each gotten activity
AcitvityName.finish();
or via or via getParent().finish(); ?
This did not help me: Best way to quit android app?
FD
#Override
public void onPause() {
if(isFinishing()){
//code to finish() all activitys threads etc.....
}
super.onPause();
}
in onPause() you can check for isFinishing() and then if it is finishing it goes to onDestroy() so you can execute some code youd like
Use a broadcast receiver to call all your activities and call finish locally in them, invoking the current lifecycle callbacks.
Broadcastreceiver and Paused activity
http://developer.android.com/reference/android/content/BroadcastReceiver.html
Android don't allows user close application directly. You may minimize it to background or directly killing process.
But if you want to call some callbacks and release any resources when user remove your application from screen - you may to do following:
Clearing activity stack in onDestroy method (or if you wish in onBackPressed, onHomePressed). It must calls onDestroy methods in all removing activities so you may release any extended resources in onDestroy method of activity which has links on it.
So when user exit from your application - it will remove his activities and release all resources.
I need a method to detect when my application is closing, so that I can tell a web-server to clear my session variable that it's storing. Is there any way to do that?
I'm assuming your application extends Activity.
You could use the onDestroy() method:
From the docs :
onDestroy() is The final call you receive before your activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
Your code would look like this:
public class YourAppActivity extends Activity {
...
...
#Override
protected void onDestroy() {
super.onDestroy();
//clear your session variable.
//you may want to do this quick, and on another thread
//to prevent android from killing your app
}
}
check
Activity Lifecycle and
i think you can do it on onDestroy()
You could try onDestroy() which is run when the app is being destroyed by the system or onStop() when the app loses visibility (often prior to destroying). You code would then look something like this:
public void onDestroy() {
super.onDestroy();
//Enter your code here to do stuff
}
However, on destroying your app the variables used by it will be destroyed along with it.
See: How to release or clear the value of variable or object?
For this you have to create static variable for counter of integer type. On OnCreate method Increment variable by 1 and on OnDestroy() Method decrement the variable value. and on OnDestroy() Method check the static variable value is 0 or not if it is 0 then call the webservice to clear the session
I would use the Activity's onDestroy() method checking whether the user is terminating the app or the OS is killing the process' activities because of low memory with the isFinishing() method. To deploy the "Destroy web session" logic, you could start an IntentService to start this action.
Hope it helps.
I am using Application class to share global variables across activites and I am setting them in onCreate method of application class. When I start app variables values are set in onCreate and while using app in activities I am changing values of varables. When I exit app and start it again I am getting old values, the last values of variables set in activities. Thats mean onCreate of Application not running on starting app again. This is code in onCreate method of Application class.
#Override
public void onCreate() {
super.onCreate();
application = this;
category = 12;
subCategory =22;
}
It looks like old application object is still in memory and it is not calling onCreate on starting app 2nd time.
What is need to be done so that onCreate of application class run again or where to initialize variables in application class so that code runs everytime.
please declare your application class name in manifest file.
like below
<application
android:name="com.tt.app.TTApplication"
android:label="#string/app_name"
In the Application class, the onCreate() method is called only if the process was ended when you exited the application. Usually the process is stopped when the system needs memory or if you exit the app using the back button instead of the home button. However, you cannot rely on it being terminated.
However, the right way of passing parameters between activities are intents or preferences. In your case, I have the feeling that preferences is the way to go.
If you really want to kill your process when exiting the application, you can call
System.exit(0); when the user presses the back key on your first activity. This is definitely not recommended since it means fighting against the way the Android OS works and might cause problems.
More on this here: Is quitting an application frowned upon?
There is probably an instance of your application still in the memory.
Recheck your life cycle methods and make sure that the application is exiting properly.
Also check if any of your activities are leaking memory.
I had the same problem with my app where onCreate() method of Application class just triggered for the first time when my app is loaded. Daniel's solution of using System.exit(0) did the trick but this solution lead me to another problem. After using System.exit(0), onPause(), onStop() and onDestroy() method of my foreground activity did not get called.
Well, that was a reasonable behavior for an app because If you use System.exit(0) then you application will be removed from System's process queue and there will be no way for an android to execute onPause(), onStop() and onDestroy() method for my foreground activity.
The workaround I used for this problem was to finish my activity when back button is pressed and after some time killing my applications process like below:
public void killApp(){
final Thread threadKillApp = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, "Going to kill app");
android.os.Process.killProcess(android.os.Process.myPid());
}
});
threadKillApp.start();
}
Calling killApp() method just after calling finish() on my activity did the job.
Check the Activity life cycle. Do what you want in onResume() instead.
try to use onStart() method or onResume().
Your onCreate method should look like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(someView);
}
your onResume Method should look like this:
#Override
public void onResume() {
super.onResume();
variable = someVariable;
}
I have an application that has a user log in and log out. On a log in it tells my DataBase that the user is online. Problem I am having is that when the user doesnt use the app for a while and the processor kills my app is there a method or something where i can run my last piece of code to log them out? I looked at the android life cycle and i cannot use destroy because that only ties with that activity. Thanks!
I found a solution for this - not perfect but worked for me.
1.) Create a service to run in the background which is started when the first activity is created.
2.) Each activity binds to this service so it can "check-in" (i.e. it is alive and onPause) hasn't been called)
3.) In each activity register a broadcast receiver that listens for an intent fired by the service on a regular basis.
4.) On receiving the chech-in intent, it calls a service method which basically lets the service now there is an activity that is still alive (I tent to only respond to the intent if it had windowFocus
5.) If there is a check-in the service sleeps and then re-requests a checkin, if there was no check-in it sleeps for a shorter period of time, before re-requesting a check-in, if none respond then the app logs out. (The reason for the second re-quest when no check-ins were found was to account for issues surrounding check-in during an activity transition, i.e. starting a new activity and closing the current one).
As I said this isn't the nicest way to do it but seems to work for my needs so far.
why can't you use onDestroy method of your activity? if you have a lot of activities, you can create your own base activity class and derive all your activities from this base class.
public abstract class BaseActivity extends Activity {
....
#Override
public void onDestroy() {
super.onDestroy();
// do your stuff here
}
}
and thenm create all your activities like this:
public class YourActivity extends BaseActivity {
...
}
In AndroidManifest you've got name. Now create
public class MyName extends Application {
}
this is your Application class which is automatically created once user open your app. Now simply override onTerminate() method inside MyName class.
#Override
public void onTerminate() {
user.logOut();
super.onTerminate();
}
You can use your MyName class in every Activity simply with this code:
MyName myName= (MyName) this.getApplication();
myName.logUser(user);