Confused by asynchronous mechanism - android

I am confused by the fact that android is multi-threaded. If the code of a particular activity method is executing, can it be interrupted in the middle by onPause(), onStop() or onDestroy() or by another method like the onPostExecute() of an asynctask?
Edit 1
This question is not about activities life-cycle. What i am really asking is if the onPause() method can interrupt the onClick() method (just an example) and i would like to read more about how exactly android manages activities, calls their async methods etc...
Edit 2
Ok, it seems that i have found the relevant information i needed in the developer docs (don't know if it is explained better somewhere else): Threading Performance:
Internals
The main thread has a very simple design: Its only job is to take and
execute blocks of work from a thread-safe work queue until its app is
terminated. The framework generates some of these blocks of work from
a variety of places. These places include callbacks associated with
lifecycle information, user events such as input, or events coming
from other apps and processes. In addition, app can explicitly enqueue
blocks on their own, without using the framework.
It states that callbacks relative to activity lifecycle, user events such as input and other code are all managed using a "thread-safe work queue". This is central to understanding Android asynchronous programming. It explains a lots of things, such as why onClick() will be never be interrupted by activity onPause(), or why onClick() will be never be interrupted by a runnable posted using a Handler object (allocated in the main thread). So, for example, the onPostExecute() of an AsyncTask cannot interrupt the onClick() method (or onStart(), onResume(), onPause() etc...). As a novice android programmer, it was a bit confusing at first.

According to your question, I think you need to understand basic about Android Application's life cycle.
Basically, the life cycle deals with the state of application in different different situation.
Like what will be state when application goes, in foreground or background and all that So These cycles state that you had mentioned like onPause(),onDestroy(), onStart(), onCreate().
Now talk for AsynchTask(), If you want to execute long running process like downloading image or listening musing or any other then we will use BackGround services. So don't get confusion between life cycle method and background services. .
Third, App will close only some rare condition like if memory is not sufficient or some other fatal issue occur in App then only it will terminate.
So, findings are that Thread is meant for long running process and Activity Life Cycles method are meant for various activity state
Please follow this tutorial and I hope you will get clarification

This is a good question to ask I think. However, Here is my understanding:
When an Application starts, a Dalvik Virtual Machine (DVM) is assigned to it and works separately. So no two Applications interrupt each other as each of the application is managed by separate DVM.
Coming to Activity, it is a component of Android and runs on main thread. Android OS manages priority level to it's components. It gives high priority level to Activity, Services and may be other component(s). The OS maintains the non interruption behaviour of main thread.
Further when you run an AsyncTask, it is a long running task in background but dependent on Application context. So the OS does not guarantee to manage it.
Now regarding activity life cycle. As #nihal_softy said, activity has it's own life cycle which start from onCreate() and encounters onStart(), onResume(), onPause(), onStop() and onDestroy(). You can call these methods from anywhere of your Activity or from an AsyncTask and it will called but does not mean that the Activity will go in background or will destroy. In a simpler word, if you call onPause() from an AsyncTask, it does not mean that the Activity will be sent to background (if in foreground). Because when an Activity will go in background then it calls it's life cycle methods such as onPause() and onStop() as callback. But converse is not true.
I hope my understanding will help you to get the answer.

Related

Why Activities are designed where it allows to call onDestroy() after onCreate()?

One scenario where an activity does not go through its full life cycle is where there is a requirement to make a decision (may be via an if condition inside onCreate()) and kill the activity immediately by calling Finish() inside the onCreate() method itself. onDestroy() is called after onCreate() when this happens.
This clearly is a deviation from Activity lifecycle. My question is
1) Why is such behavior allowed by Android? Any possible reasons for this?
2) Are there any other ways that this kind of decision making functionality be implemented? Are there any built in facilities like say a widget or background method who does this for the programmer?
Activity is not going through the documented life cycle of onCreate() OnStart() onResume() onPause() onStop() and then onDestroy() is bypassed to make it onCreate() and then onDestroy() without other methods
It is going through the portion of that lifecycle that is appropriate for the situation. Quoting the documentation: "The visible lifetime of an activity happens between the call to onStart() and the call to onStop()". Hence, in situations like this, where the activity is never visible, there is no need to call onStart(), onResume(), onPause(), and onStop().
From a programmer's perspective these kinds of exceptional cases always add to complexity of learning something
These sorts of complexities are commonplace in software development for pretty much any platform and environment.
So, I wanted to know if there was any valid reason behind allowing something like fall to finish() inside onCreate().
Nobody but you knows what you would consider to be "any valid reason".
Most likely, this as an optimization path, to save on CPU time, battery, and possibly some memory, by skipping unnecessary work. Please bear in mind that Android was designed around hardware from a decade ago, where mobile CPUs had ~1% of the processing power of today's devices, let alone devices that may arise in the future.
When you navigate from one activity to another and you don't need the first activity to be living anymore (like a splash screen), you might be calling the following from somewhere in the first activity:
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
startActivity(intent);
finish();
And if you don't call that finish method and allow that splash screen to be in resumed state. What happens when you press the back button from your SecondActivity? You will see the splash screen again! Imagine how horrible that would be. The intention of this Android framework is not to make you pass through all the lifecycle methods of an Activity, but to provide you whatever facilities that you need in your app. I think this example can help you understand why such behaviour is not allowed by Android.
As understood from other answers for this question, activities are designed in such a way that they need not go through or invoke all the methods in its life cycle.
Common situations where programmers design activities that do not pass though its full life cycle are like, requirement to display a splash screen. Another requirement is for any any task that does not require a UI at all, and finish() is invoked inside the onCreate() method itself. In this case, as the question suggests, onDestroy() is called immediately after onCreate() without invoking other intermediate methods of activity life cycle.
However, I am not sure about android providing any widgets for any such specific tasks, but it always makes sense to perform any such non-UI tasks in a service rather than an activity whenever possible. It is up to the programmer to decide what is apt for a given requirement.

How to manage stopping a Service with a long-running onDestroy?

I have an android Service class which has a long running onDestroy. I need to prevent this as it can cause a hang when there are activities running.
It seems some people are happy starting a thread/AsyncTask in the onDestroy method to hold the long running code, though I'm concerned that the threads may be killed. Another solution may be to use startService instead of stopService with an intent that tells the service to start a shutdown thread which calls stopSelf at the end.
Are any of these solutions sensible, or is there another way?
A shutdown Intent is a reasonable way to go here.
Starting another Thread in onDestroy is a bad idea though. It might be called or not called when you don't expect or want it.
Edit: To persist important information neither of these ways is a good idea.
You cannot assure that these methods actually get run before your process is killed. For non-important data you could of course go these ways, but you'd better persist your data as soon as you get it, or at least within a fixed interval (if you have a continous data input).
From the official Documentation:
Note: 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.
And here the Documentation specifcally for services:
Called by the system to notify a Service that it is no longer used and is being removed. The service should clean up any resources it holds (threads, registered receivers, etc) at this point. Upon return, there will be no more calls in to this Service object and it is effectively dead.
(I've included the Activities documentation, because it is more precise)
You should be aware that there is no absolute guarantee for onDestroy to be executed.
It seems some people are happy starting a thread/AsyncTask in the onDestroy method to hold the long running code, though I'm concerned that the threads may be killed.
I would assume that you're trying to either free some resources or send some sort of message to server.
In case of resources there is no need worry - if you'll start new thread it will be killed only together with hosting process (your app). If that would happen - it's ok, system will release resources for you.
In case of server message - that is a bit more complicated. I like your idea with sending command to a Service instead of calling stopService. Other option would be to start another tear-down Service from your onDestroy which will perform long running operation and shut down itself.

Where is the best place to start a long running, application-wide, background task

I have a long running background task that I would like to start when the app launches and shutdown when the application shuts down. I'm already quite aware of the activity life cycle and what gets called when an activity gets created and destroyed.
I'm coming from an iOS background, and over there we have some calls that are made during application startup and shutdown. Is there something similar in the android world? I've searched a lot and all I'm finding are answers relating to an activity, not the entire application.
(Android is relatively new to me, so I may just not know the correct terminology to search for.)
EDIT:
I'll try an be a bit more specific. I have a background task that needs to be continuously running while the user is using the application. It will be streaming data from a server continuously while the application is active. It does not need to run when the application is in the background. It doesn't seem to make sense to me to tie the startup / shutdown of this background process to any one single activity since it may not be the same one activity that starts up when the application becomes active.
I am (possibly mistakenly) assuming that the OS takes care of starting / stopping background threads when the application resumes and pauses. If that is, in fact, the case, then all I really need to do is spin up the background task when the application first launches, i.e. when it is loaded into memory and becomes active for the first time that session.
It doesn't seem to make sense to me to tie the startup / shutdown of this background task to any one single activity since it may not be the same one activity that starts up when the application becomes active.
That's reasonable. It is somewhat difficult to implement, though.
I am (possibly mistakenly) assuming that the OS takes care of starting / stopping background threads when the application resumes and pauses.
You have it exactly backwards. Android pays not one whit of attention to any threads that you fork yourself, directly or via thin wrappers like AsyncTask.
In addition to that point of confusion, you appear to be equating "user switching to another app" with "app shutdown". Those may be the same thing in single-tasking operating systems. They are not the same thing in Windows, OS X, Linux, Android, etc.
So, what you seem to be seeking is having a background thread running doing this streaming work while your UI is in the foreground, and then stop when your UI is in the background. The problem is that there really isn't a straightforward way of accomplishing that in Android.
One close approximation would be to create and register a custom Application class, where you override onTrimMemory(), and stop your background work when you get to TRIM_MEMORY_UI_HIDDEN, TRIM_MEMORY_BACKGROUND, TRIM_MEMORY_MODERATE, or TRIM_MEMORY_COMPLETE -- whichever of those that you encounter first. If, when one of those arrives, you determine that your streaming thread is still outstanding, shut it down.
In terms of startup, you could use onCreate() on that same Application singleton. The problem is that this will be called on any process creation, which may include scenarios in which you do not have UI (e.g., you are responding to some system broadcast, like ACTION_BOOT_COMPLETED), or possibly your process is going to parts of your UI that do not depend on the streaming. If you have none of those scenarios, then onCreate() in Application would be fine. Otherwise, kick off the streaming in onCreate() of whatever activities need it.
While normally we manage long-running threads with a Service, that is for cases where we explicitly want the thread to continue after our UI is in the background. Since you do not want that, you could skip the service.
It depends on what you want to do exactly. When you're just interested in the app starting for the first time you could #Override onCreate().
Or maybe you want to use onResume() as this will get called whenever a user brings the app to the foreground.
But this really depends on what exactly your background task is doing and what you want to do with it, to get an exact answer you need to provide more details.
Here is an overview for the actiity life cycle that should help you:
You can extend the default Application class and implement it's onCreate() method to detect when the app is launched. There is no corresponding method for when the app gets closed though.
Do not forget to specify it in the Manifest file.
In Android the application isn't shut down unless the system runs low on memory. You won't get a warning about that, it will just call your Service's onDestroy lifecycle method. If you want to do it when the Activity is visible on screen, use onStart and onStop. If you want to do it when the Activity is resident in memory, use onCreate and onDestroy.

Android background thread management and activity lifecycle

I have an activity in which I collect data for an online transaction. When the collection is done, I run a background thread (more specifically an AsyncTask) that calls a web-service and waits for its response, then return it to the activity. Meanwhile, a progress dialog shows up.
I want the background process to be cancelled if the application finishes or user cancels (however, I still need to notify the web-service), and retained if the activity is destroyed due to a configuration change or to free memory. I understand that I shall use onRetainNonConfigurationInstance() to detach my activity from the AsyncTask, retain it, and then reattach in the next activity, I already have the infrastructure for that. I also know that in some lifecycle callback, the isFinishing method tells me if my app is shutting down normally; and I do believe I can also handle the user cancel in the progress dialog's callback.
I have two simple questions:
Will onRetainNonConfigurationInstance() be called if my activity is
killed due to low memory? (I know it will be if the reason is a
configuration change.)
What is the situation (as emphasized by the developer guide) in which onStop() and onDestroy() are not called? (I want to know if my
code handling the cancellation would always execute.)
All in all, can I be sure that by implementing onRetainNonConfigurationInstance() and onDestroy() with isFinishing() checked, in every situation, my background thread will be handled accordingly?
BONUS question: If my application is killed for some reason (let's say permanently), how can I provide a way for the AsyncTask to save the response anyway? Can I retain an instance of shared preferences in it and write the data in that?
Will onRetainNonConfigurationInstance() be called if my activity is killed due to low memory?
No. Your activity is never individually killed for low memory. Your whole process may be terminated due to low memory, but onRetainNonConfigurationInstance() is only designed for in-process use.
What is the situation (as emphasized by the developer guide) in which onStop() and onDestroy() are not called?
Your process could be terminated due to low memory conditions (onStop() is very likely to still be called, but onDestroy() might not be if Android is in a hurry, such as due to an incoming phone call). Also, your app could crash with an unhandled exception. I am not certain if onDestroy() is called if the user force-stops you, but I doubt it.
All in all, can I be sure that by implementing onRetainNonConfigurationInstance() and onDestroy() with isFinishing() checked, in every situation, my background thread will be handled accordingly?
"Every" is a strong word. If Android terminates your process, your thread is gone as well.
If my application is killed for some reason (let's say permanently), how can I provide a way for the AsyncTask to save the response anyway?
Write the data to disk before doing anything else, and hope you are not killed before that point. Then, next time you run, notice that this saved data is floating around and arrange to do the rest of your work on it.

Android; Using a Service to subscribe/unsubscribe to an Observable object, good idea?

I have a requirement, whereby when a user clicks a button, then an object needs to be observed. When the user clicks that button again, the observation stops.
My initial thought is to have the button bound to a method in the activity using the onClick="myMethod" in the layout file.
When this method is invoke it will call startService() which starts observing the object. By this I mean it registers the service as an observer.
When the button is clicked for a second time, it calls the stopService() method which un-registers the service as an observer.
My thoughts for using a service is so the observation; and subsequent actioning is taken off the UI thread. Is this a reasonable approach or is there something in the Android SDK that could do this easier?
My thoughts for using a service is so the observation; and subsequent actioning is taken off the UI thread.
Only if you fork your own thread, and only if the "observation" supports alternative threads. Services are in the "background" from a UI standpoint (they do not draw on the screen directly), but they are not in the "background" from a threading standpoint by default.
Is this a reasonable approach or is there something in the Android SDK that could do this easier?
That is impossible to answer given what you have written above. You seem to think the button is important -- probably, it's not. What probably is important is what this "object" is that you are "observing"...and you didn't say what it is.
If your service will reliably unregister itself in stopService(), you should not run into garbage collection issues with this approach. However, threading with respect to the observer/observable pattern usually is the responsibility of the observable -- in this case, the mysterious "object".
I agree with Murphy however a small point i think i should give you:
1. what are you doing when the activity is destroyed ? paused ?
2. if the object u are observing is generating events that you need to observe you have to think what happens to them in all situations, if the observer object dies with the activity, i think u are better off with async task or local thread, in any case you will also have to discover that the activity was destroyed in your service in order to GC the observed object or kill the service too in the Activities onDestroy.

Categories

Resources