How does Android Volley stop/cleanup its dispatcher threads - android

Looking at the source code of the Volley library, I'm curious of how exactly does the "cleanup" of the dispatcher threads work. A RequestQueue contains one CacheDispatcher instance and an array of NetworkDispatcher instances. Both of these dispatcher classes extend Thread and are started as soon as they are created. After that, they run in an infinite loop until their quit() methods are called.
My question is, how are those threads actually stopped (i.e. what, if anything, prevents them from running indefinitely until the system kills the app), for example when the user leaves the application. The quit() methods of the dispatchers is called only from the RequestQueues stop() method, but that method itself isn't called from anywhere in the Volley, aside from the start() method to cleanup the possible previous dispatchers before initializing the new ones.
What I am sort of aiming at with the question is how much of an issue are the idle threads, and how they behave when the task (i.e. a group of activities) goes from the foreground to the background and hangs around for a while. Androids task switcher can hold quite a bit of apps (altough some of them might have been ejected/stopped), and most of them presumably use libs like volley/okhttp/picasso which have their thread pools. In theory that could add up to quite a lot of threads (albeit idle).
I understand this is a fairly low-level question and would probably require a lot of theory to explain correctly, if someone can provide a satisfactory answer touching on the bold stuff above, I'd be happy to accept it.

Related

What would cause a thread interrupt?

I'm familiar with both what an interrupt is used for (to put it roughly: asking the interrupted thread kindly to terminate or at least stop its work as soon as conveniently possible, instead of killing it immediately) as well as how to handle it properly (in most common cases, maybe not the tricky ones).
But I'm having a hard time to understand who (if not my own code) could even call Thread.interrupt() in the first place, and when this "third party interrupt" could occur.
I'm finding lots of information on why anybody would want to interrupt a thread, but hardly anything about who would do that for "my" threads unless I coded it myself.
So on Android, if my own app code does not contain any calls to Thread.interrupt() or something similar like AsyncTask<,,>.cancel(), will any thread I start ever be interrupted at all?

Android AsyncTask vs Thread + Handler vs rxjava

I know this is the question which was asked many many times. However there is something I never found an answer for. So hopefully someone can shed me some light.
We all know that AsyncTask and Thread are options for executing background tasks to avoid ANR issue. It is recommended that asynctask should only be used for short-running tasks while thread can be used for long-running tasks. The reasons why asynctask shouldn't be used for long tasks are well-known which is about the possible leak caused by asynctask since it may continue running after an activity's destroyed. That is convincing. However, it also leads to some other questions:
Isn't thread also independent from activity lifecycle? Thus, the risk with asynctask can also be applied to thread. So why thread is suitable for long-running tasks?
Looks like the risk of asynctask is only applicable when using it with activity. If we use it in service (not IntentService since IntentService stops after its work's completed), and as long as we can guarantee to cancel the asyntask when the service's stopped, can we use it for long-running tasks? and doesn't it means it's risk free to use asynctask in services?
I've played with rxjava for a while and really like it. It eliminates the need of worrying about threading (except you have to decide in which thread to subscribe and observe the emitted data). From what I can see, rxjava (in conjunction with some other libs like retrofits) seems to be a perfect replacement of asynctask and thread. I'm wondering if we could completely forget about them or there is any specific case that rxjava can't achieve what asynctask and thread can do that I should be aware of?
Thanks
Since no one's replying. I'm answering my own questions then.
The reason why AsyncTask is recommended for only short tasks (around 5 seconds) is there is no method to cancel a running AsyncTask. There exists a method called AsyncTask.cancel(true) which invokes onCancelled(Result result). However, according to the docs, this method "runs on the UI thread after cancel(boolean) is invoked and doInBackground(Object[]) has finished." (https://developer.android.com/reference/android/os/AsyncTask.html). On the other hand, Thread can be stopped with Thread.interrupt().
There shouldn't be any problem running an AsyncTask within a Service provided that you are aware of the cancellation limitation of AsyncTask and the possibility of memory leak can be created by AsyncTask. Note that, there is obviously no need to use an AsyncTask in an IntentService which is already running in a worker thread.
This is a very experience-based question. I guess there would be no complete answer. What we can do is to understand Rx and being aware of the its limitations to determine where suitable to use it. In my development work, I use RxJava all the time without having any issue. Note that the same memory leaking issue is also applied to RxJava. You can perhaps find one of the specific questions here. There are also a whole bunch of discussions about handling leaking/screen rotation with RxJava that can be easily found by Googling.
AsyncTask and Thread+Handler are not carefully designed and implemented. RxJava, Akka and other frameworks for asynchronous execution seem more carefully developed.
Each technology has its limitations. AsyncTask is for a single parallel task with ability to show progress on UI. However, if activity is regenerated (e.g. because of screen rotating), connection to UI is lost (one possible solution for this problem is at https://github.com/rfqu/AsyncConnector).
Thread+Handler keeps memory for thread stack even when there is no messages to process. This limits the possible number of threads. You can have much more Akka actors or RxJava Subscribers than handler threads, with similar functionality.

asynctask doInBackgound() not running if there's a asynctask already running

When the user logs in into my app. I am starting an asynctask to maintain the user session. And that async task is running indefinitely till the user logs out. My problem is that when I try to start other asynctasks, their doInBackground() method is never executed.
I read somewhere that if an async task is already running, we cannot start new async task. I can confirm this because when i removed the user session async task, it worked properly. Is there a workaround?
P.S.: I have already used executeOnExecutor() method. but it didn't help.
For potentially long running operations I suggest you to use Service rather than asynctask.
Start the service when the user logs in
Intent i= new Intent(context, YourService.class);
i.putExtra("KEY1", "Value to be used by the service");
context.startService(i);
And stop the service when the user logs out
stopService(new Intent(this,YourService.class));
To get to know more about Service you can refer this
Service : Android developers
Service : Vogella
To know more about asynctask vs service you can refer this
Android: AsyncTask vs Service
When to use a Service or AsyncTask or Handler?
I read somewhere that if an async task is already running, we cannot start new async task.
Yes,That is fact that you can't run more then 5 (five) AsyncTaskat same time below the API 11 but for more yes you can using executeOnExecutor.
AsyncTask uses a thread pool pattern for running the stuff from doInBackground(). The issue is initially (in early Android OS versions) the pool size was just 1, meaning no parallel computations for a bunch of AsyncTasks. But later they fixed that and now the size is 5, so at most 5 AsyncTasks can run simultaneously.
I have figure out Some Threading rules and i found one major rule is below ,
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
What is definition of AsyncTask?
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
How & Where use it?
AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended to use it.
Why you can't use multiple AsyncTask at same time ?
There are a few threading rules that must be followed for this class to work properly:
The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN.
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
Running multiple AsyncTasks at the same time — not possible?
Test sample of parallel excution of AsyncTasks
Try Executor
You should go with Executor that will mange your multiple thread parallel.
Executor executor = anExecutor;
executor.execute(new RunnableTask1());
executor.execute(new RunnableTask2());
...
Sample Example 1
Sample Example 2
Just like a few others here, I object to the premise of the question.
Your core problem is that you are using an AsyncTask to perform a task beyond its scope. Others have noted this too. Those who offer solutions that can mitigate your problem through low-level threads (even java.util.Concurrent is low-level which is why Scala uses Akka actors as an abstraction), Service, etc. are quite clever, but they are treating the symptom rather than curing the disease.
As for what you should be doing, you are not the first to want to maintain a user session in an Android application. This is a solved problem. The common thread (no pun intended) in these solutions is the use of SharedPreferences. Here is a straightforward example of doing this. This Stack Overflow user combines SharedPreferences with OAuth to do something more sophisticated.
It is common in software development to solve problems by preventing them from happening in the first place. I think you can solve the problem of running simultaneous AsyncTasks by not running simultaneous AsyncTasks. User session management is simply not what an AsyncTask is for.
If you are developing for API 11 or higher, you can use AsyncTask.executeOnExecutor() allowing for multiple AsyncTasks to be run at once.
http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor(java.util.concurrent.Executor, Params...)
I'll share with you, what we do on our App.
To keep user Session (We use OAuth with access/refresh tokens), we create a Singleton in our Application extended class. Why we declare this Singleton inside the MainApplication class? (Thats the name of our class), because your Singleton's life will be tided to the Activity that has created it, so if your Application is running on low memory and Garbage Collector collects your paused Activities, it will release your Singleton instance because it's associated to that Activity.
Creating it inside your Application class will let it live inside your RAM as long as the user keeps using your app.
Then, to persists that session cross application uses, we save the credentials inside SharedPreferences encrypting the fields.
yes starting 2 or more asynctasks simultaneously may cause issues on some devices. i had experienced this issue few months back. i could not predict when the 2nd asyncTask would fail to run. The issue was intermittent may caused by usage of memory as i was executing ndk code in asynctask. but i remember well that it depended on memory of device.
Similar question had been asked before. I would post the link for the similar question.
AsyncTask.executeOnExecutor() before API Level 11
Some users suggest go for Service. My advice is don't go for that path yet. Using service is much more complicated. Even you are using service, you still have to deal with threading, as
Note that services, like other application objects, run in the main
thread of their hosting process. This means that, if your service is
going to do any CPU intensive (such as MP3 playback) or blocking (such
as networking) operations, it should spawn its own thread in which to
do that work....
If we can solve a problem in elegant way, don't go for the complicated way.
I would suggest that, try one of the APIs in java.util.concurrent as suggested in below
AsyncTask is designed to be a helper class around Thread and Handler
and does not constitute a generic threading framework. AsyncTasks
should ideally be used for short operations (a few seconds at the
most.) If you need to keep threads running for long periods of time,
it is highly recommended you use the various APIs provided by the
java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and
FutureTask.
I can't give you any code example so far, as I do not know how you design your session managing mechanism.
If you think your long running session managing task shouldn't bind to the life cycle of your main application life cycle, then only you might want to consider Service. However, bear in mind that, communication among your main application and Service is much more cumbersome and complicated.
For more details, please refer to http://developer.android.com/guide/components/services.html, under section Should you use a service or a thread?

AsyncTask for longer than a few seconds? [duplicate]

This question already has answers here:
Android AsyncTask for long running operations
(4 answers)
Closed 9 years ago.
The API reference states,
AsyncTasks should ideally be used for short operations (a few seconds
at the most.)
Is the problem with a doInBackground that takes, say, 30 seconds that the thread pool might run out of threads? And if that's the reason, would it cease to be a problem if I ensure my app will never have more than one such long running doInBackground executing concurrently?
The answer given by #Walter Mundt is correct. Nevertheless, I would like to add a complement of information and give a pointer to a library that can be used for long running AsyncTask.
AsyncTasks have been designed for doing stuff in background. And, yes, it's right that if your AsyncTask lasts for two long, then you will face 2 different issues :
Activities are poorly tied to the activity life cycle and you won't get the result of your AsyncTask if your activity dies. Indeed, yes, you can but it will be the rough way.
AsyncTask are not very well documented. A naive, though intuitive, implementation and use of an asynctask can quickly lead to memory leaks.
RoboSpice, the library I would like to introduce, as proposed by #Walter Mundt, uses a background service to execute this kind of requests. It has been designed for network requests (potentially long running by nature), but it could be easily adapted to execute just long running tasks, unrelated to network. I would be glad to add a patch to it.
Here is the reason why AsyncTasks are bad for long running tasks. The following reasonning is an adaptation from exerpts of RoboSpice motivations : the app that explains why using RoboSpice is filling a need on the Android platform.
The AsyncTask and Activity life cycle
AsyncTasks don't follow Activity instances' life cycle. If you start an AsyncTask inside an Activity and you rotate the device, the Activity will be destroyed and a new instance will be created. But the AsyncTask will not die. It will go on living until it completes.
And when it completes, the AsyncTask won't update the UI of the new Activity. Indeed it updates the former instance of the activity that
is not displayed anymore. This can lead to an Exception of the type java.lang.IllegalArgumentException: View not attached to window manager if you
use, for instance, findViewById to retrieve a view inside the Activity.
Memory leak issue
It is very convenient to create AsyncTasks as inner classes of your Activities. As the AsyncTask will need to manipulate the views
of the Activity when the task is complete or in progress, using an inner class of the Activity seems convenient : inner classes can
access directly any field of the outer class.
Nevertheless, it means the inner class will hold an invisible reference on its outer class instance : the Activity.
On the long run, this produces a memory leak : if the AsyncTask lasts for long, it keeps the activity "alive"
whereas Android would like to get rid of it as it can no longer be displayed. The activity can't be garbage collected and that's a central
mechanism for Android to preserve resources on the device.
Progress of your task will be lost
You can use some workarounds to create a long running asynctask and manage its life cycle accordingly to the life cycle of the activity. You can either cancel the AsyncTask in the onStop method of your activity or you can let your async task finish, and not loose its progress and relink it to the next instance of your activity.
This is possible and we show how in RobopSpice motivations, but it becomes complicated and the code is not really generic. Moreover, you will still loose the progress of your task if the user leaves the activity and comes back. This same issue appears with Loaders, although it would be a simpler equivalent to the AsyncTask with relinking workaround mentionned above.
Using an Android service
The best option is to use a service to execute your long running background tasks. And that is exactly the solution proposed by RoboSpice. Again, it is designed for networking but could be extended to non-network related stuff. This library has a large number of features.
You can even get an idea of it in less than 30 seconds thanks to an infographics.
It is really a very very bad idea to use AsyncTasks for long running operations. Nevertheless, they are fine for short living ones such as updating a View after 1 or 2 seconds.
I encourage you to download the RoboSpice Motivations app, it really explains this in-depth and provides samples and demonstrations of the different ways to do some background operations.
If you are looking for an alternative to RoboSpice for non network related tasks (for instance without caching), you could also have a look at Tape.
I believe that AyncTasks are in general still tied to the foreground activity stack that spawned them, so that e.g. if an Activity spawns an AsyncTask, the user leaves the app, and then the OS is short of memory, it will kill the Activity's process (including the still-running AsyncTask), and just expect you to restore the state and start over if the user resumes/returns to your app.
For longer-running tasks, particularly the sort where there will only be only one or a few, you probably want a Service instead, because those can persist even when your app's UI is shut down to save memory.
Disclaimer: I haven't done Android coding in awhile, so this answer may be out of date or based on a flawed understanding of how things work. I will remove this caveat if someone with more recent experience can comment to confirm; high-rep folks are welcome to just edit this paragraph away instead if they know this is correct.

Android how many threads can I have going?

I have an Android app that has separate things going on but are all basically threads (and definitely are threads to the Android debugger)
There are multiple animation listeners that loop and call each other
There is a countdown timer that is always counting down to zero after it is initiated
Now I need to consider adding more countdown timers. How many of these kind of looping processes can I have going on? In this particular implementation I am not concerned about performance, efficiency, etc, until it becomes apparent.
Insight appreciated
I would be very surprised to learn that you exhausted the number of threads you can use safely in an android application, as long as you are properly managing their lifetime and prevent "busy loops"and the like from occuring.
One thing I did learn though, I am pretty sure you can only have 5 asynctasks operational at any time, and they will arbitrarily continue to exist and get killed or respawned by themselves if you start new ones...ie if i turned an asynctask on then off five times the debugger will say 5 async threads operational, but I can continually toggle on and off as much as I want because the resource pool will kill the oldest dead asynctask.
There is no maximum that I know of. I can tell you, however, that you most likely don't NEED that many threads.
You can keep countdown listeners in a single thread using Android's Handler, specifically the postDelayed() method. Start a Looper in a separate thread, and use a Handler to manage the timeouts -- don't busy wait, or sleep-loop.
I don't believe countdown timer will create threads--it should simply add your task to a queue on your main thread from the looks of it.
All your listeners should take place on the same thread as well (there is a single thread that manages all listeners (for visible objects anyway).
So you probably aren't using anywhere near as many threads as you think you are. If you were creating a lot of threads I'd be worried--they are really hard to keep synchronized and may cost you a lot more than you'd gain, but with the structures listed I'd go ahead and allocate as many as you feel appropriate (but test for performance on a cheap device of course)

Categories

Resources