What is recommended to do for networking job that should fetch and update new data? I see different answers on that issue.
To create a Service that will run inside a new Thread that should make all the network job OR to create a new Thread that will start a Service inside that Thread?
You can't make a Service that runs inside a Thread, so that possibility is impossible. You need a Thread (or AsyncTask) to do any network request. If you want the app to continue to do network requests even if the current Activity is finished, then yes you need to create that Thread (or AsyncTask) in a Service.
In android all The network operations are to be done within a thread. Even if you are creating a service all network operations will be done within a thread.
Service within a thread is not possible.
Now if You want your network operations to be available in multiple activities you should create a service otherwise A separate network thread within an activity will do the job.
IntentService initializes on the main thread in onCreate and runs in a separate thread otherwise. No need to deal with extra threads in this case. A Service runs in the main thread and requires that you handle the threading (if needed). It would be best to prototype an IntentService since you're just making a network call. If the network call is short, then just use an AsyncTask.
I think you need IntentService. No need to confuse on Service inside Thread. Start Service inside background thread or start a service with background thread .Both are same.
It is always better to call thread inside service rather than service inside thread because service is a component of android so it is having some priority level. On the other hand Thread is not a part of Android component so it is having no priority compared to service.
So in case of low memory when Android system starts killing application, it will first kill thread that contains the service because of its lower or no priority. And if you have used Service containing thread then you are good. Hope it helps :)
Related
I have started a Background Service.
I am aware that this is started on the main thread and so I have create new thread/runnable within the Background class.
I seem to be spending a lot of time managing how to prevent the thread and background service continuing, which is leading me to believe I may be better off using an Intent Service and run it at the specified timer interval from my main activity.
The background service is currently performing a network operation once every 10 seconds and then sleeping.
It also uses a broadcast intent to send info to any listening activities.
My question is: When I kill the Background Service (either by stopSelf(); or if I use a bound service the 'unbind' command, will this also kill the created thread without me explicitly calling thread.interrupt?
Is this an efficient way of utilising a background service given the added need for threading?
Service callbacks run on the main thread just like activities' (unless otherwise specified). I seem to stumble upon lots of advice here on SO that goes something like "start a thread in a service [to do work in the background]". That doesn't make sense to me. What does it matter if I start a thread from activity code compared to service code, just as long as there exists a started service component in the application process?
If the answer is what I think (that it doesn't matter) then it's a shame that people give the impression that a service object needs to be somehow related to the background thread.
The term "background" can be misleading when it comes to Services as it can have two meanings. Services are used, simplistically talking, to run tasks even if there is no Activity of your application running. To clarify, think of a music player; you want the music to still play even if the Activity is not running. That is the definition of background that doesn't have to do with Threads; you are running a portion of your application in the background because you do not have any visible component of your app on the screen (maybe some Notification but no full screen UI).
Now, lets say you want to download some data from the internet. As you might know, you cannot perform long running tasks in the UI Thread (as of API 11+ you will get a NetworkOnMainThreadException), so you need to use a background Thread. Let's say you do not want to use an AsyncTask to download the content because a Service is better suited for your needs. In this case, you will have to start the Service on a background Thread. That is the second meaning of background, which basically means creating a new Thread. Android provides a class that does exactly this; IntentService. It is a Service that runs on a background Thread and that it finishes itself when the given task is done.
It does not matter where you actually start a thread if the lifetime of that thread is reflected via your app process state: http://developer.android.com/guide/components/processes-and-threads.html#Lifecycle
Android does not care if there is a Thread running or not. Threads just run even when your app is considered an empty process "that doesn't hold any active application components." Don't abuse that, since users don't want that apps are secretly active although they look dead.
If you want (and you should) that Android does not kill you randomly although your threads are not done you have to make sure that you keep e.g. a Service in started state.
Creating a thread from within a Service (or just using IntentService) will primarily result in better, simpler & cleaner code. For example because a Service has a Context and you can't leak your Activity from there. You also get free callbacks from the system.
And leaks via threads are extremely easy.
new Thread(new Runnable() {
#Override
public void run() {
SystemClock.sleep(Long.MAX_VALUE);
}
}).start();
Will leak your activity if you just put it in e.g. onCreate because the anonymous inner Runnable keeps a reference to your Activity and will not release it until the thread stops running and is itself garbage collected.
In case you really know what you are doing, feel free to start threads in Activities and sync their lifecycle manually to some empty Service. I would not recommend it because it's unlikely to be less work to do that correctly.
I am still confused at threads. Still I could see some answers which points to threads, UI thread, background thread, main thread etc. (mostly on AsyncTasks and updating UI from background threads etc.)
Could anyone give me a complete explanation around these or some links at least?
It would be great if the answer covers the following cases:
Which are all the threads that's involved:
When I am running an activity (setting the content view, attaching some buttons, some dialog messages)
An activity with AsyncTask
A Background Service
A HTTP call
UI thread (main thread) - it is crucial to instantiate (add) all UI elements on this thread, that is why it has a nickname UIThread
AsyncTask - has methods doInBackground, onPostExecute, etc. Sort of its own lifecycle
Background Service (service) A service runs by default in the same process as the application. in its own thread. (as pointed out by #MisterSmith) A service runs by default in the same process as the application. in its own thread. Therefore you need to use asynchronous processing in the service to perform resource intensive tasks in the background. Services which run in the process of the application are sometimes called local services.
Thought you can specify to run a Service in its own process:
Running a service in its own process will not block the application in case the service performs long running operations in its main thread. But as the services runs in its own process you need to use some interprocess communication (IPC) to communicate to your service from other parts.
HTTP call executed using HttpClient (from docs:
Thread safety of HTTP clients depends on the implementation and
configuration of the specific client.
), has to be executed on non-UI thread by using new Thread(new Runnable(...)).start();, otherwise you will get NetworkOnMainThreadException thanks to #vikram. But it seems that HttpClient.execute() method is executed in a thread, that is why it requires a handler as one of the parameters in order to pass the result to the corresponding handler (handler runs on UI thread and can update widgets (UI elements) as it is needed)
Extra:
To force something to be executed on your main thread use yourContextInstance.runOnUiThread(new Runnable(....));
In order to determine if current thread is UI(main) thread:
Looper.getMainLooper().getThread() == Thread.currentThread();
Interesting question about threads in a service:
Does a runnable in a service run on the UI thread
Why UI thread is responsible for all this?
Because UI thread is in charge of dispatching the events to the
appropriate widgets (UI elements), which includes the drawing events
Sources: this that and a little bit of that and some of that
When I am running an activity ( seting a content view , attaching some buttons, some dialog messages )
Usually only one thread (the main one, sometimes incorrectly called UI thread).
Activity - with async task
Again, by default only one (the main one). Menus and button handlers also run in the main thread. AsyncTask is a different story. It creates a worker thread (btw you should be careful not to leak it when exiting the activity).
Background Service
A service runs by default in the main thread. So do broadcast receivers. And this is why the main thread is not (only) the UI thread. Some types of services (like the popular IntentService) spawn a worker thread though.
An http Call
Is a synchronous operation, so it blocks until it completes (and this is why you should never perfom one in the main thread).
Technically speaking an application can have as many threads as it wants, they are arbitrarily created by the programmer.
However, the standard android application by default has one thread. That is the main thread, and is often referred to as the UI thread (as it is the only thread with access to the UI). By default everything happens in the main thread.
If you run an async task, different parts run in different threads, here's a basic breakdown:
onPreExecute() runs in the UI thread and is first called when you execute an async task.
doInBackground() runs in a newly spawned thread separate from the main/UI thread.
onPostExecute() runs in the UI thread after the background task returns.
A background service runs entirely separately from the application, it can run indefinitely even if the original application is destroyed.
An http call happens on whatever thread you call it on, but as a requirement of newer android API's you can no longer do any network activity from the main/UI thread. (This will actually cause an exception and terminate your application) This is to prevent slow network calls from blocking the main thread and therefore creating a choppy user experience.
Which are all the threads that's involved:
When I am running an activity (setting the content view, attaching some buttons, some dialog messages)
UI Thread or Main Thread is involved here.
An activity with AsyncTask
Both UI Thread and WorkerThread is involved.
AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
The 4 steps
When an asynchronous task is executed, the task goes through 4 steps:
onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). This method is used to display any form of progress in the user interface while the background computation is still executing.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
A Background Service
The IntentService class provides a straightforward structure for running an operation on a single background thread. This allows it to handle long-running operations without affecting your user interface's responsivenes
A HTTP call
NetwokrkOperation can't be executed from UI Thread ( or MainThread). So use alternatives like AsyncTask or HandlerThread
Related posts:
Handler vs AsyncTask vs Thread
Why use HandlerThread in Android
Asynctask vs Thread vs Services vs Loader
Pardon my questions, as I'm still very new to programming so I don't fully understand the concepts of mainthreads, and async tasks, and services, and threads. I'm reading the documentation about Services for Android because I want to perform some tasks off the main thread. It says:
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.
1.Are they saying that a "thread" stops immediately after you leave the app (i.e: Home button)?
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.
2.If threads are baked into Java, why does android have AsyncTasks?
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.
3.Does this basically mean, that almost every service is basically going to have a thread created inside it?
4.Would it be bad to start an AsyncTask inside of a service?
1.Are they saying that a "thread" stops immediately after you leave the app (i.e: Home button)?
A Thread should be destroyed when the Thread that started it is destroyed. So, if you start a Thread in an Activity then it should be destroyed when that Activity is destroyed or transferred to a Service. For instance, you can start music in a Thread and update the songs there but if you want it to keep playing when the Activity is destroyed then it should be moved to a Service
2.If threads are baked into Java, why does android have AsyncTasks?
An AsyncTask allows you to perform background work and easily update the UI before, during, and after the background work is done by utilizing any of its built-in methods except for doInBackground() because it is the only one that doesn't run on the UI Thread
3.Does this basically mean, that almost every service is basically going to have a thread created inside it?
Not necessarily but you could create a Thread inside of it
4.Would it be bad to start an AsyncTask inside of a service?
No. You could do this.
AsyncTask is a great way to do background work. Its methods make it very easy to update the UI. But you need to read through the documentation carefully (maybe even a few times) to make sure you completely understand how to use them. Also, remember that these are for short-lived operations so they can be good for downloading network data but shouldn't be used for things that last more than a few seconds (According to the docs)
A thread doesn't stop immediately when you leave the app. The suggestion to use a separate thread is only so you don't block your app's GUI.
AsyncTasks actually use a ThreadPool behind the scenes as creating a thread is an expensive process. If you have many short lived tasks, using AsyncTask is just a quick, easy, but efficient way to execute them without blocking your application's GUI.
Yes, essentially. A service is more heavy weight than a thread though. Using a service in place of a thread is not a good idea. Also services can actually be made to execute on a whole other process. Just FYI.
No. It would be a good idea, if you've many short lived tasks to execute.
If you are only trying to execute tasks off the main thread, you don't need a service. Just create another thread.
AsyncTask behind the scenes just submits your task to a thread pool for execution. If you have many short lived tasks, like parsing networking traffic, AsyncTask is great.
However, if you are handling a huge amount of requests, you might want more control over the thread pool executing your tasks.
No
Because a main thread controls the UI while asynctasks can make heavier tasks while keeping the UI lag-free.
No, but if you want your service to make heavy lifting like loading stuff from internet then it should use an asynctask. Most services are used to load data from internet so most of them have asynctasks. Note that for the service to be kept alive after the activity dies, you must specify it. Services by default die along with the activity unless configured properly
No
You might be confusing by thread and task and process.Task is small kind of process.An process
is a pro-gramme that running in your system example when start your task-manager it is showing all the process running like Internet-explorer but thread is small lightweight process means you can say sub-process that in execution for performing some task but asynchronous in android is just similar to thread but it may-be long.Take a example in android you are playing temple-run in android-phone ,and some-one is calling you so that high priority task will performed and current thread is paused there and so many method are there
like onCreate() ,onPause(),you can understand it.
Is there any way on Android to know, if the thread running my code, is the UI Thread or not ? In swing there was SwingUtilities.isEventDispatchThread() to tell me if i am on the UI Thread, or not. Is there any function in the Android SDK that lets me know this ?
Answer borrowed from here: How to check if current thread is not main thread
Looper.myLooper() == Looper.getMainLooper()
Any Android app has only one UI thread, so you could somewhere in the Activity callback like onCreate() check and store its ID and later just compare that thread's ID to the stored one.
mMainThreadId = Thread.currentThread().getId();
Anyway, you can omit checking if you want to do something on the UI thread and have any reference to Activity by using
mActivity.runOnUiThread( new Runnable() {
#Override
public void run() {
...
}
});
which is guaranteed to run on current thread, if it's UI, or queued in UI thread.
Yes, there is a way.
Check the current thread object against main lopper's thread object. Main looper is always in the UI thread.
boolean isOnUiThread = Thread.currentThread() == Looper.getMainLooper().getThread();
Hum actually due to Android architecture, all Activities run in the main thread, ie the UI thread. So when you are coding an activity, everything that is in your Activity is in the UI thread.
That is why in Honeycomb an error have been added when you are making network calls in the main thread : it totally blocks the UI.
So by default you are in fact always working in the UI thread.
Another thing : unless you explicitely ask it to be in another thread, a Service will operate on the same thread as the activities of its application.
So, what to do ?
When you have to do heavy calculation in your activity; one solution is to use an AsyncTask (a class designed to allow you to easily use another thread). The code in onExecute() is run in another thread (but be cautious postExecute runs in your main thread). Another one is to manually start a new thread when AsyncTask is not really adapted.
If you create a service that does costly background tasks, make it run in another thread with the android:process=":my_process" attribute of the manifest. You will need to create an AIDL to communicate with this separated service, but it is not a complicated task.
Many objects, like for example the MediaPlayer, have Async variations of their methods. Try to to always use them.
Put a breakpoint where you want to check and, when it gets hit, check if you can interact with your UI (ie, if the UI is not frozen). If you can't interact with the UI then you are in the UI Thread, otherwise you are in a background thread.