I am developing an Android application that notifies a user when data is uploaded to the internet from one of my activities. When the user closes the application through the menu I have implemented, I execute code to remove the notifications I have placed:
notificationManager.cancelAll();
The problem is the user can kill my application through the multitasking menu (the more likely way to quit) and the code is not executed.
I thought over riding the onDestroy method would solve my problem:
#Override
public void onDestroy()
{
super.onDestroy();
notificationManager.cancelAll();
}
however, this method does not seem to be called every time the application is quit from the multi-tasking menu.
Is there a way to remove my notifications before the system kills my process?
Thank You!
Unfortunately, I think better way to handle this doesn't exist. System should invoke method onDestroy(), but you have no guarantee it does.
onDestroy Android Reference
There are situations where the system will simply kill the activity's hosting process without calling this method (or any others) in it.
Related
I am using some AsyncTasks in background for purposes in my Native Android Java application, however when i click the button "Apply changes and Restart Activity", once the activity is restarted AsyncTasks execute twice. this is really strange. because i have some monitoring purposes with AsyncTasks, so i used new MyAsyncTask.Execute() for execute the class in a Handler up every 1 minute. if application run normally, it's very cool. but when i used to restart by the mentioned Button in Android studio, i am facing the issue. with this issue, i am in a trouble that some logs are duplicating.
It is relative to the place of your asynctask execution. By click button , in oncreateview or in oncreate of your activity. You can have debug in start of your asynctask(preexecute or doinbackground) and for every time execution check the variables of your activity(if your asynctask is inside of your activity).The best way for recognizing of time proper of your operations , is checking of some parameters of your activity inside of your asynctask and selecting of proper time for operation doing.Do not forget the place of your asynctask also is important but you must have your controls inside of the asynctask.
If you share your code it may be easy to understand, but it seems you only have a problem with the application's life cycle, see the documentation:
Understand the Activity Lifecycle
The issue is originally from android architecture. when Activity gets destroy, automatically the activity restarts several times in same thread. in case of that single execution may run several times. the following code helps to solve this issue.
#Override
protected void onDestroy() {
pusher.disconnect();
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(1);
super.onDestroy();
}
I have a simple app that counts steps using Sensor.TYPE_STEP_DETECTOR. This sensor is NOT unregistered after the app is set into the background, meaning it continues to track steps even when it's not in focus. Once the app resumes, the step counter UI gets updated with whatever steps were counted since it was last in focus.
My goal is to have the app save the data after it's been closed in the background. It already saves it onPause() but I haven't found any method related to when the app is closed.
At first, onDestroy() seemed like the obvious place, but it's not guaranteed to be called since it only seems to be called when something calls finish() or if the system wants to clear up space.
I've also seen solutions involving using a background service or Job Scheduler. A background service wouldn't work since as of API >= 26 the background services stop after several minutes. I think Job Scheduler wouldn't work since I won't know when the user might close the app and I want the steps to be as accurate as possible, so finding an interval for when to schedule the jobs would be difficult.
I'm looking for a simple spot to basically do what my onPause() method already does.
#Override
protected void onPause() {
super.onPause();
saveSteps(currentSteps);
running = false;
}
What is exactly the problem? Do you just want to replicate the onResume somewhere else?
If so you could do that at the onRestart/onResume function since the sensor isn't unregistered you could get the same results , but I don't see how that would change things for you.
I've using some code for a sign in screen that forces the app to close if the user doesn't want to sign in. If the user chooses to not sign in/cancel, it calls the code to exit the app. I've successfully done this two ways (not at the same time) with:
finishAffinity();
System.exit(0);
and
finish();
System.exit(0);
Yet both lines of code seem to do the same thing... The app is closed to the user, yet remains in the background apps to be reopen if the user hits the 'overview' button they can select it to reopen. (Which just restarts the prompt to sign in.)
Since I notice no functional difference, I'm wondering what is the difference between finishAffinity() and finish() methods?
Bonus Question: Also, is there a way to completely shut down the app, so it also doesn't appear in the overview button app list?
finishAffinity():
Closes all the activities present in the current Stack
finish()
Closes only opened activity
Also, is there a way to completely shut down the app, so it also
doesn't appear in the overview button app list?
Yes you can add android:noHistory="true" to your activities tag in the Manifest.xml for this pupose
finishAffinity() : finishAffinity() is not used to "shutdown an application". It is used to remove a number of Activities belonging to a specific application from the current task (which may contain Activities belonging to multiple applications).
Even if you finish all of the Activities in your application, the OS process hosting your app does not automatically go away (as it does when you call System.exit()). Android will eventually kill your process when it gets around to it. You have no control over this (and that is intentional).
finish() : When calling finish() in an activity, the method onDestroy() is executed this method can do things like:
Dismiss any dialogs the activity was managing.
Close any cursors the activity was managing.
Close any open search dialog.
finishAndRemoveTask() method pop out all your activities from stack and removes the application from recent task list simple finish this current activity as well as all activities immediately below it in the current task that have the same affinity,
finish() method pop out your current activity from stack.
for detail document link
finishAffinity(): finish the current activity and all activities immediately below it in the current task that have the same affinity.
finishAndRemoveTask(): call this when your activity is done and should be closed and the task should be completely removed as a part of finishing the root activity of the task.
I've searched everywhere a manner to have the equivalent of a main() function (yes function not method) inside a Android application but failed...
Typically what I would want to do is:
void main()
{
// do some really nice initialisations stuff here
// ... let the app does his life, I really don't care
// do some final stuff here before leaving
}
The nearest approach I've seen so far is to use a SplashScreen and override the OnCreate() method. The problem is that is not acceptable from my point of view.
Why? Because a SplashScreen is nothing than an Activity tagged as a LAUNCHER.
That makes it to appear in the apps list, thing I don't want when I develop an app widget.
Furthermore, where to place my code just before the app destroy? In the onDestroy() method?
No, once again, this is not reliable. Android can decide to delete my instance whereas the application is still running.
Well, in fact, I take for principle that every components of my app are running in the same process since I don't mention explicitely in the Manifest that I wan't a component to run in its own process.
In the case of an app widget, I've placed my init code on the first call of onUpdate() method. I think it's a good bet. Then this app widget (AppWidgetProvider more precisely) is in charge to launch any activity as its will.
The "DataBase" for all the app is defined in a separate Singleton like this:
public class MyDataBase {
public static MyDataBase getInstance() {
if (instance_ == null)
instance_ = new DataBase();
return instance_;
}
public void load();
public void save();
static MyDataBase instance_ = null;
public int myInt;
public String myString;
public Object myObject;
etc..
}
With this Singleton I'm sure at least, its lifecycle is the same as the entire app itself.
To back with that AppWidgetProvider, I have to trick a little. Indeed, Android can decide to delete its instance whereas some other activities are still on place and the process is still running. So for example, systematically loading my DataBase in the first call of the OnUpdate() is unnecessary and overkill. What I do is having a static boolean value that indicates if the DataBase have been loaded for the lifecycle of this process or not.
Thus, the AppWidgetProvider can be instanciated tons of time, as long as the Singleton DataBase persists (so the process), it will not reload the DataBase each time, got it?
(yes difficult to be clear...)
About the cleanup code of the app, I thought to override the finalize() method of my DataBase Singleton, but well, I'm really not sure it's a good idea since the moment of the call of this method is totally unpredictable. I suppose it would be called if you suddently power off your Android, but well I'm not sure of anything here, thus so far, I didn't found a solution for that part.
Any comment or something less tricky that what I currently do is welcome.
Thanks.
onResume() is the function that will be invariably reached before starting you app, so you could either put the 'main' code in the onCreate() method or the onResume().
onPause() is ALWAYS called before destroying the app, either by the user or the OS.
There is great explanation regarding the lifecycle in the Android documentation:
http://developer.android.com/training/basics/activity-lifecycle/starting.html
For the initialisation you can over-ride the onCreate method of the Application class:
Called when the application is starting, before any activity, service, or receiver objects (excluding content providers) have been created. Implementations should be as quick as possible (for example using lazy initialization of state) since the time spent in this function directly impacts the performance of starting the first activity, service, or receiver in a process. If you override this method, be sure to call super.onCreate()
Termination is harder to deal with. You'll probably have to monitor each component of your application separately. If you are targeting API level 14 or later you can use Application.registerActivityLifecycleCallbacks to help with this.
The nearest approach I've seen so far is to use a SplashScreen and
override the OnCreate() method. The problem is that is not acceptable
from my point of view. Why? Because a SplashScreen is nothing than an
Activity tagged as a LAUNCHER.
It's because Android is formed with several activities and those activities have life cycles. So every activities start from onCreate() then finishes at onDestroy().
http://developer.android.com/training/basics/activity-lifecycle/starting.html
That makes it to appear in the apps list, thing I don't want when I
develop an app widget. Furthermore, where to place my code just before
the app destroy? In the onDestroy() method? No, once again, this is
not reliable. Android can decide to delete my instance whereas the
application is still running.
In a scenario that user presses home button to exit from your app, your current activity is more likely to invoke onPause() method (only when the activity has no other processes to finish). However, when user force closes (terminates) your whole application by ending process. Then you don't have to worry about invoking any methods or what so ever because Android itself will close anything related to your application automatically.
To back with that AppWidgetProvider, I have to trick a little. Indeed,
Android can decide to delete its instance whereas some other
activities are still on place and the process is still running. So for
example, systematically loading my DataBase in the first call of the
OnUpdate() is unnecessary and overkill. What I do is having a static
boolean value that indicates if the DataBase have been loaded for the
lifecycle of this process or not. Thus, the AppWidgetProvider can be
instanciated tons of time, as long as the Singleton DataBase persists
(so the process), it will not reload the DataBase each time, got it?
(yes difficult to be clear...)
The example you have posted for singleton database connection is not bad I think, but there are better ways to get the job done cleanly and more effectively. For example hibernate framework connection pooling
I have a kid's app for Android and there are some unique considerations for this application since the app has basically no navigation (it's for young kids). I do not want to break my app UI (which has been successful on iPhone) by adding a quit/restart button.
What I really need is fairly simple -- I want my activity/app to start clean and new every single time it starts. Whether it's an initial load or whatever -- basically any time onResume is called I want a completely fresh instance of my app.
I initially thought I could just exit/quit/finish the app when the user leaves. But I haven't found a way to do this that doesn't cause crashes on start. Also every thread/stack overflow post about that idea is filled with people wagging their fingers and saying you should never ever quit an app on android.
If I can't quit the app onExit, is there something I can do to restart my activity every time onResume is called? (or would that be an infinite loop?).
Would greatly appreciate any help!
Try starting your main activity in onResume, and clearing the activity stack:
public void onResume() {
super.onResume();
startActivity(new Intent(this, MainScreen.class).addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
}
maybe these aren't the correctl flags to add, but check out the other Intent flags and this could do what you want!
intent flags documentation
Ended up getting it to work fine by calling finish() in onPause().
Again, I appreciate the advice from people saying "this is not how Android does things". I've got a pretty good understanding of the best practices at this point. This is an unusual situation for an unusual type of user.
in your reload you can try this..
onStop();
onCreate(getIntent().getExtras());