I'm working on an Android project, in which I need to load some images to a GridView. The images could be in the cache, if cache missing, then query the Internet server. My design is to use two threads to do the loading task. One thread for reading cache and one thread for downloading. So there are 3 threads including the UI one. Each of them has its own message queue and uses Handler to communicate.
My question is whether I should use bound service in this situation instead? Actually I have realized the design above and it seems nothing wrong but GC is working very hard, which can be inferred from the logcat.
Another issue is that several threads exist when I use DDMS to monitor the threads. This is because the same loading mechanism is used in several Activities. I have let the threads quit its message loop while onPause() is called, I'm sure only two of them are alive in the same time. But I can see all of them in DDMS. (BTW, why the threads still exist? I have let thread = null;)
So in a word, my question is: Could this loading task benefit from a bound service?
So why are you using multiple threads? You need to load an image in the background, and when done, display it in the UI. It really doesn't matter to the UI where the images comes from. And using multiple threads doesn't make it faster, just consumes more memory. Just use a single background thread: first it hits the cache, then downloads if no hit.
Services are for when you want do something that doesn't need a UI. If you need to update the UI in real time, a service doesn't make much sense.
Related
I want to prevent the thread from stopping during the transition between activities and call this thread during the start of my application. I have one option and I would like to share it. So far, I have stopped at writing an android service in which to include the beginning of the stream that, I need to perform. And then call it in the class inherited from the application class. It is important to note that my thread will send certain data to the database every minute. Perhaps you can advise a more reliable and popular way to solve the problem.
Threads don't stop between Activities. That would be impossible to do safely- threads cannot in general be safely stopped by anyone but the thread itself without risk of data corruption or deadlock. So Android doesn't even try. (You can cancel a thread from another thread, but that works by setting a flag and hoping that the thread you want to cancel looks at it occasionally to honor it.)
The real problem is twofold
1)How do you know if the thread is already running so you don't launch it again. This is solvable in a variety of way.
2)Do you want the thread to work when the app is in the background? This is the real problem, because Android kills background apps regularly, which will end the thread. There is no reliable way to make a thread run constantly in the background in Android. Here your best bets are either a foreground service running to keep the app active, or to not use a thread and make your app even t driven (for example, setting a repeating alarm for every 15 minutes and running then).
I want to have various asynchronous threads in app like around 5-10 threads for background tasks which can be long running (like streaming) and I am also updating the UI to post some results if necessary.
From what I have heard that AsyncTask has problems with:
Long running tasks,
Having poorly being tied to Activity life cycle,
Device orientation problems, and
Memory leaks and so on.
So, I am looking an alternative (possibly without using any third party libraries) which doesn't have these above problems.
Should I be better off with using Simple Java Threads? I don't mind using them given that they won't give any problems that are with AsynTask.
In most scenarios AsyncTask should suffice the requirement. However there are scenarios where AsyncTask can't be used. ie AsyncTask manages a thread pool, from which it pulls the threads to be used by task instances. Now the thread pools assume that they'll get their threads back after a reasonable period of time. So in a scenario where you do not know how long you'll need the thread you can't use an AsyncTask. And as of Android 4.4 , the size of thread pool can grow only to : (no of CPU cores * 2) + 1. So on a dual core processor, the maximum number of threads you can create is limited to 5.
So, I am looking an alternative (possibly without using any third party libraries) which doesn't have these above problems.
Coming to the alternatives to AsyncTask, these are the available options:
Handler
Runnable
Now there are cons to all background threads no matter how beautifully illustrated they are, few include:
The possibility of user's interaction while the background thread is processing. If the work that the background thread performing is altered, you'd need to communicate it back to the background thread. java.util.concurrent has many classes to help in these scenarios
The possibility of the process itself being killed while the thread is performing tasks. So in these cases instead of using an AsyncTask or the simpler Thread a Service or IntentService would be an ideal option.
The possibility of an error occuring inside the background thread, such as retrieving data from server while connectivity is lost, you'd need to manually shut down the background thread.
In short: Whichever option you choose, you'd need to manually handle
all corner cases for the efficient and splendid working of the app.
PS:
[Citation] : The busy coder's guide to Android development v5.8 by #Commonsware which is released under the Creative Commons Attribution Non-Commercial Share Alike 4.0 License
Long running tasks,
Having poorly being tied to Activity life cycle,
Device orientation problems, and
Memory leaks and so on.
Simple java threads are not going to solve any of these problems. Specially, memory leaks.
If you just want to load data in background, you can think about Loaders. They cache the data application wide and fit nicely with activity/fragment life cycle.
Alternately, you can go through this article to know about services (if you don't know already) and see if they are suitable in your scenario.
I would first suggest to use the above mentioned components,
Handlers
Runnables
If the operation is long running then you can go for service as it runs continuously. You said
which can be long running (like streaming)
If you are streaming over some audio or video then it is best to use a service either a normal Service or an Intent Service depending on your requirements.
You can destroy the service when ever needed or let the Android system do it when required.
Hence I would suggest you to use a Service in such a scenario.
Could you pease tell me what is the correct way to do the synchronization jobs in Android (e.g. if I have about 5 jobs)?
Note! By synchronization job I mean a thread which runs in background and sends some data (e.g. analytics) via a Web Service...
For more details please read a more detailed description:
I've got a task to implement some background jobs which will synchronize some data with a restful web service. Some of the jobs should be scheduled periodically with a specific delay. If there is no internet connection then I simply cache the data and later when the connection reappears I try to run the jobs.
Taking into consideration that creating new threads is quite expensive and especially on mobile development, I'm using a cached thread pool (ExecutorService) and every time some actions are requested for processing I'm trying to reuse the threads. I don't use AsyncTask because I've replaced this with this Executor Service (Executors.newCachedTreadPool) and its convenient for me because I don't need to create many AsyncTasks as I reuse the threads from ES... In order to support the scheduled jobs, I use another thread pool(ScheduledExecutorService) and use Callable because I need to see the execution result. I've got a complex logic here... So, when a particular action is done in the app, the 1st thread pool (is like the AsyncTask) will work like an AsyncTask, the advantage is that I don't create new threads but I reus them. This will not block the UI's main thread. It will delegate to the scheduled executor which will do its job.
This solution works. And it sounds good for me as I'm coming from server side, but I'm interested to know how this must be done correctly on Android? Is this too sophisticated for a mobile app?
Merci,
Serge
Use a sync adapter. See http://developer.android.com/training/sync-adapters/index.html. A sync adapter runs in the background, it's managed by the system, and scheduled efficiently so that your sync doesn't waste battery power. Best of all, the system will automatically detect network connectivity and queue up your sync adapter if necessary. If you want, you can use multiple sync adapters.
Notice that although it seems that sync adapters need a content provider and an authenticator, they really don't.
I am doing a web application which has Java as a front end and shell script as a back end. The concept is I need to process multiple files in the back end. I will get the date range from the user (for example from July 1st-8th) and for each day process around 100 files. So in total I have 800 files to process.
I will get these details from JSP and delegate a background call to shell script and get back the results and display the same to the user.
Now I did all these in a sequential approach - by which I mean without threads. So there is only one main thread that executes and the user has to wait till 800 files are processed sequentially. However this is really slow. And because of this I am thinking of going for threads. Since I am a beginner of threads, I read a some stuffs regarding this and I have come up with the following idea:
As I read threads work have to be split .. I thought of splitting the
8 day work to 4 threads where each thread would perform 2 day work
I would like to know whether I am following a correct approach and my major concerns are:
Is it recommended to spawn multiple threads from a web application
Whether or not this is a good approach
Some guidance of how to proceed with this. An example instance would be great. Thank you.
Yes, you can run the long processing job in multi-threaded or in any high performance environment. You should also you Servlet 3.0 Asynchronous Request Processing to suspend the request thread and wait till the Long processing task is done.
Yes, there's nothing wrong with spawning multiple threads from a web application. In fact, if you're running a Servlet container (which you most likely are since you're using Java), it's already spawning multiple threads for you. In general a Servlet container will automatically spawn a new thread (or reuse one out of a pool) to handle each request it receives.
Your approach is fine, thought you'll want to fine-tune the number of threads to something that is suitable given the hardware configuration of your system and the amount of concurrent load on your web service. Also note that while spinning up a bunch of threads will reduce the total amount of time needed to process all the data, it will still leave a potentially large chunk of time before any data is ready to go back to the user. So you might get a better result by doing smaller work units sequentially, and posting each batch of results to the user-interface as soon as it is ready. Then it will still take a long while for the user to have all the data, but that can start viewing at least a portion of it almost immediately.
The way to improve user experience is not by parallelizing at Servlet level on 100000 threads but rather to provide incremental rendering of the view. First of all it would be useful to separate your application in multiple layers, according to the MVC pattern for example.
Saying that, you will have to look on how
Create a service that is able to return partial answers and a last answer, meaning that all available data has been returned. Each of this answers can be computed in parallel to improve performance.
Fill a web page incrementally, tipically by calling back this service which returns a JSON string you use to add data to the DOM. Every time you get an answer, if this is a partial answer, you call again the service providing the previous sequence number.
If you look to Liligo to understand, you will see how this is works. The technique I described is known as polling, but there are others technique to obtain similar asynchronous results at UI Level. In general, you don't want to work directly with the Servlet API, which is a very low level API,but rather use a reasonable framework or abstraction for that.
If you want a warm advice, you should have a look to the Play! framework http://www.playframework.org/documentation/2.0.2/JavaStream HTTP streaming.
Create threads in a web application is not a good solution. It is a bad design because normally it would be the container (web server) who is charged with that activity. So I think you have to find another solution.
I suggest you putting the shell scripts in cron, scheduled to run each minute, and to "activate" them you can touch files that act as semaphores. At each run the scripts verify if the web application touched the semaphore file, if so they read the date interval from those files and then start to process.
When should a thread or a service be used?
Should they be used for authentication? For instance, in my app I was considering using a thread or service (I am authenticating via Active Directory.)
Do you have examples of when each would be used?
Update: It seems the Android documentation includes a corresponding clarification now, see http://developer.android.com/reference/android/app/Service.html#WhatIsAService.
Original answer:
In Android, a Service does not provide any concurrent execution ("run in background"). It is actually more of a simple Java object which merely is instantiated (and managed) via the Android system instead of your application via new.
The most important property of a service is therefore not about deferring workload; this can be achieved with simple threads.
What makes a service object special is that it is registered with the Android system as a service. This let's the system know that this object provides some sort of service and should be kept alive as long as possible, or until it is stopped. Normal application threads do not have this special meaning to the Android system and will be terminated much more generously at the discretion of the system.
So, if you need some background activities to go on only while your application/Activity is active, a thread can do what you need.
If you need a component that keeps active will not be purged even when, after a while, the Android system decides to remove your Activities from memory, you should go for the service, or even a "foreground service", which is deemed even more important by the system and even less likely to be terminated to reclaim resources.
Of course, if desired, a Service object can also be made to contain one or more Thread instances which could then live as long as the Service object itself.
Edit:
Oh, plus: A service is, of course, the way to go if you want to provide some service(s) to other applications, which can "bind" to a service only.
A thread should be used in a long running process that would block the UI from updating. If it's more than a second or two you might want to put it into a background thread and notify the user with a dialog or spinner or something. If you lock the UI thread for more than 5 seconds the user will be prompted with a "kill or wait" option by the OS.
A service does not run on separate thread, so it will block the UI, but you can spawn a new thread within a service. A service is used more for something that should happen on an interval or keep running/checking for something when there is no UI shown.
Just look at this nice post Android Thread Constructs(Part 4): Comparisons
.
or Difference between Service, Async Task & Thread?.
Use service if you need something that is either used by other applications or outlives your application activities. The good example of service is file transfer that may take long time and you don't want to force user using your application during this time. Use thread (usually via AsyncTask or similar) in other cases.
For authentication purposes AsyncTask seems like a good choice.
I believe the main difference is about Android system attitude. Service is a part of android infrastructure, so android recognizes service as a working part of application and considers killing service as a last option. Moreover, you can tune up service priority in order to do it as important as foreground activity. As for threads, android does not recognize a thread as important part which must be kept. So usual threads has much more chances to be killed.
For instance If you have an activity which start a working thread and then go background, as android do not recognize thread as a working part, it may think that application do nothing, because no activity or service running and kill the whole app, including the working thread.
As per Android Developer Guide (http://developer.android.com/guide/components/services.html#Basics) :
A service is simply a component that can run in the background even when the user is not interacting with your application. Thus, you should create a service only if that is what you need.
If you need to perform work outside your main thread, but only while the user is interacting with your application, then you should probably instead create a new thread and not a service. For example, if you want to play some music, but only while your activity is running, you might create a thread in onCreate(), start running it in onStart(), then stop it in onStop(). Also consider using AsyncTask or HandlerThread, instead of the traditional Thread class. See the Processes and Threading document for more information about threads.
Remember that if you do use a service, it still runs in your application's main thread by default, so you should still create a new thread within the service if it performs intensive or blocking operations.