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();
}
Related
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 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.
I searched through most answers here and all suggest we add a flag to the intent to kill old activities. The problem is my activity only receive intents from other app and has no control over it.
More specifically, my activity receive an intent to load a picture, then it uses Asynctask to load and do some complicated background processing of that picture, say, may be 2 minutes.
If the user at this moment back out (assuming that only onStop is called, not yet onDestroy) and share another picture to the app , this will start a new activity, and the previous activity cannot be accessed, but its Asynctask hold up the thread so that my new activity just freeze without starting its own Asynctask.
(I later tried the parallel thread executor, but this doesn't stop the old thread from running, thus consuming computational resources).
Any idea what I should do?
(I don't want to stop the task in onStop as this is to easy to be called. But I do want to stop the task if new picture is shared, since it is no longer needed.)
(The Asynctask will spit out a huge array of self-defined Objects declared in the main activity, and thus the activity gets immediate updates of the result from the background process, and the UI updates immediately after onPostExecute is called.)
EDIT:
It seems that your problem is that you're trying to do all this image processing work in asynctasks launched by your activity. Have you considered changing your app architecture to rely all this background processing to a service?
You can use the activity to show some UI information while you process the image in your service, or if you don't need this UI just simply communicate with the service (through broadcast, for example) to provide it the image and let the service show some information of the process through notifications.
If you don't want to keep your activity alive when you exit it you can use
android:noHistory="true" in your activity declaration at the manifest
More info here
This is the workaround, and seems it is working very well for the moment:
After getting a sharedpreference prefs, do this in onCreate:
prefs.edit().putBoolean("ForceClose", true).commit();
In the onPreExecute() of the AsyncTask, put:
prefs.edit().putBoolean("ForceClose", false).commit();
In the doInBackground() of the AsyncTask, constantly check for
if (prefs.getBoolean("ForceClose", false))
cancel(true);
and call finish() in onCancelled() to finish off the activity.
I am writing my first android app so I will try my best to be clear and precise. I can see some similar questions to this but none that seems to answer it exactly so perhaps it can't be done but here goes:
I have got my main activity to the point where it has data stored which includes a list of apps on the device that the user has selected to launch. On clicking a button on the main activity screen I would like the device to launch each of these selected apps in turn and then (ideally) return the user to the main activity that I have written. I would also like to define some restrictions on running each app - for example, each app runs for 30 seconds or until the app stops using the internet whichever comes earliest.
I don't believe I have any issue with linking all of this to the button click, nor is there any issue cycling through all of the selected apps. What I really need is the code to launch each app and then recall from it/move to the next app (ideally after the 30 seconds or when the app stops using the internet). Hopefully the below code makes clear where I am looking for help with the TODO. Does anyone know whether this is possible and if it is how can I get it done?
public class MainActivity extends Activity {
... //some code up here
//when the Run Apps button is clicked the onClick will run all of the selected apps using this Method:
public void RunApps(View view) {
//run through the list of Apps and run the ones that are selected
for (App application : list) {
if (application.isSelected()) {
/* TODO code that is meant to run the selected app and return to the main
* activity after say 30 seconds or when the app is done using the internet.
* As a starter I have the below but this is crashing and even if it did run
* I believe that it would not return me to the original main activity:
*/
Intent i = new Intent(Intent.ACTION_MAIN);
PackageManager manager = getPackageManager();
i = manager.getLaunchIntentForPackage(application.getPackageName());
i.addCategory(Intent.CATEGORY_LAUNCHER);
startActivity(i);
}
}
};
...//some more code here
}
just a couple of notes - the App class is defined elsewhere and includes the package name and whether the app has been selected by the user. list is a List of Apps.
I believe that the ACTION_MAIN and CATEGORY_LAUNCHER values may not be the best to use and perhaps startActivity(i) is not the right method for what I want but am not sure how that needs to be changed or whether there a more fundamental changes needed.
Many thanks for any help.
You should run each app from your top-level MainActivity sequentially by invoking them one-at-a-time.
Here's how:
Keep a counter in your MainActivity to indicate which app you are
currently invoking.
Use startActivityForResult() instead of startActivity() to start
your applications. This will cause execution to return to
MainActivity.onActivityResult() when each of the apps is finished.
The requestCode of startActivityForResult() will be returned to
onActivityResult(), so you will know which application completed.
Therefore, MainActivity can increment the counter and start the
next application in onActivityResult().
Restriction:
One of your requirements is to return to MainActivity after each
app completes. These steps satisfy that requirement.
Another requirement is to return to `MainActivity after all of the
apps are finished. These steps also satisfy that requirement.
You will know when you have finished
the final app because of the value of your counter.
The final requirement is to limit the duration of each app to 30
seconds. This is a more difficult problem. You will use a Timer in
your MainActivity as a watchdog to monitor the spawned apps. Use methods
described here to stop the spawned app when time runs out:
Finish an activity from another activity.
Warning: get everything else working first, before you try to externally stop an app.
That's all. Good luck!
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());