I Want to stop all the async tasks on the device home button press, but the problem is when progress dialog is running, on home button click only the progress dialog kills and it does goto the onKeyDown() method where i have mentioned the logic to kill my async tasks. So async task runs in the background even after the application is closed and my app crashed. Is there any solution to close the progress dialog as well as all async tasks on home button click
You can't intercept calls to the home button directly.Though when the home button is pressed onPause() will be called, so you can override that method and put your logic there.
Check out http://developer.android.com/guide/topics/fundamentals/activities.html#Lifecycle for more info
In java, we can't stop a Thread which has been started and is running. So is the AsyncTask
but you can try call asyncTask.cancel() which works like thread.interrupt(). It may throw an InterruptedException. If there exists more code behind, these code will execute as well, so take care of it.
Related
I'm creating a music app in Android with a background service playing the music, and a Home activity that has various fragments and is the UI of the app.
When I press the home button on my phone, this app gets put in the background of course, and the lifecycle methods get called down to onStop(), in which the UI gets disconnected from the Service in order to allow background playback, the user can keep using their device and do other things. When I get back to my UI Activity, onStart gets called and the UI and Service reconnect together, giving me back controls over the music. onStart gets me the same activity in the foreground, it doesn't create another instance of the same activity.
I'm trying to implement also a function for when I press the back button on my device, so the UI activity can have the same behavior as with the home button, i.e. simply put the UI in the background (onStop). Instead, the default behavior of the back button is to finish(), killing the current activity it's called from (thus calling onDestroy).
What could I do for that? Couldn't really find anything online. Seems such a simple function that every music app has (not killing the app when pressing back, but just send it into background)
You can override onBackPressed and move the Activity Task to back. Based on the documentation Activity'r order in the Task will also remain unchanged:
#Override
public void onBackPressed() {
this.moveTaskToBack(true);
}
I'm writing UI tests for my application using Espresso. I'd like to test the fact that if I click the back button while a server request is in progress the app must remain where it is.
It seems not to be possible due to the espresso's architecture that makes the tests execution wait if some background operation (like AsyncTask) has been fired.
So, how can I test the following scenario:
click on a button that fires an AsyncTask
test that while the task is running and I press back button, the app stays there?
Is it possibile?
thank you
That's tricky. With AsyncTasks you cannot use Espresso while the tasks are running.
And if you would use something else for background work, Espresso does not wait, and the test finishes before the background job.
A simple workaround would be to "press" the back button without Espresso while the task is running. So, start the task, call Activity.onBackPressed() and after the task finishes use Espresso to check that the Activity is still visible:
// Start the async task
onView(withId(R.id.start_task_button)).perform(click());
// Then "press" the back button (in the ui thread of the app under test)
mActivityTestRule.runOnUiThread(new Runnable() {
#Override
public void run() {
mActivityTestRule.getActivity().onBackPressed();
}
});
// Then check that the Activity is still visible
// (will be performed when the async task has finished)
onView(withId(R.id.any_view_on_activity)).check(matches(isDisplayed()));
You can prevent the application from triggering finish() when the back button is pressed. To do so, just override public void onBackPressed() without calling super.onBackPressed(). Just like :
#Override
public void onBackPressed() {
// super.onBackPressed();
}
Additionally, if you are showing a dialog while executing the task, you can use
myDialog.setCancelable(false);
myDialog.setCanceledOnTouchOutside(false);
to prevent the button from being pushed.
Regards,
I have started a AsyncTask to decode the contents in a file on a Button click. AsyncTask is running fine, now I pressed home button. Activity entered into onStop() state. Now what happens to my AsyncTask, Will it run or stop in this onStop() state?
activity stop will not make your async task to stop. Your async task will continue and if you have some reference of view in post execute it will cause exception.
You can also use AsyncTaskLoader instead.
Read about it:
http://mobile.dzone.com/articles/loaders-versus-asynctask
No it can't be. Your activity has been stopped your AsyncTask will continues. IF you want to stop it you have to cancel your AsyncTask.
I want to know what is the best way to stop an async task frm running.
I have tried
#Override protected void onCancelled() {
super.onCancelled();
mTask.cancel(true);
}
I also tried
asyncTaskObject.cancel(true);
This works specially when associated with an event.
But suppose the scenario is--- there are 4 AsyncTask. First call the second, second calls the third and third calls fourth. When the user enters the activity there is no dialogbox.
Otherwise we could have used the onCancel method there.
When user clicks on anywhere on the page the dialog box appears if user does not click anywhere then no dialog box is shown but async task keep running in the background.Suppose the user clicks the "back" button on or the navigational icon to the home page user.is taken out of the current activity. But the async task keep running in the background and eventually the app crashes. I have used to the cancel method in onBackPressed. But the problem is you cannot be sure which task is running and app carshes again.
What is the way out of this?
keep reference to AsyncTask object as instance variable and then in onDestroy() do this
#Override
protected void onDestroy() {
if (mTask != null) {
mTask.cancel(true);
}
super.onDestroy();
}
In http://developer.android.com/reference/android/os/AsyncTask.html there's a session called Threading rules that say that AsyncTasks instances must be created on the UI thread and execute must be invoked on the UI thread. If you invoke execute from the UI thread you can cancel the thread calling yourTaskInstance.cancel(true);
I am not entirely sure when you want to cancel your tasks, but here are a few suggestions: a) keep a reference to each task that is running. b) add a dismiss listener to your dialog and cancel all tasks there (if that's what you want to do). c) cancel all tasks at the onStop callback of your activity (if that's what you want to do again).
I have a button in my application. When I clicked the button I am starting some function using thread. When the thread is running I don't want any of my view get focus (including tab also). How can I make the whole application unfocusable/untouchable till the thread completes its working?
You should show a ProgressDialog. If you don't do so, the user will think that your app is frozen. You can use the setCancelabel(false) method in order to prevent user from closing the dialog.