According to Android doc,
"...Additionally, the Andoid UI toolkit is not thread-safe. So, you must not manipulate your UI from a worker thread—you must do all manipulation to your user interface from the UI thread. Thus, there are simply two rules to Android's single thread model:
Do not block the UI thread
Do not access the Android UI toolkit from outside the UI thread"
That seems very plausible, but is it correct that the compiler does NOT complain at all if a programmer violates the second rule?
You will not get a compile-time error. You may (or may not) get a run-time error.
There are many ways to update UI like
Handler
AsyncTask
runOnUiThread method of View
BroascastReceiver
Related
I'm using a worker thread in my app so it's vital for me to know which code can be run from the worker thread and which code needs to be run on the UI thread.
In the Android documentation, the following hints can be found:
So, you must not manipulate your UI from a worker thread—you must do
all manipulation to your user interface from the UI thread. [...]
However, note that you cannot update the UI from any thread other than
the UI thread or the "main" thread.
(source)
But what "manipulation to your user interface" means in practice is often not as clear as it seems. Of course, it's clear that you cannot hide views, manipulate button texts, add list view entries, etc. from a worker thread.
But what about calling setRequestedOrientation() from a worker thread, for example? Is that allowed or does it fall under UI manipulation and thus must be called from the UI thread? Is there any way to tell or should I stay safe and better run the code on the UI thread when in doubt?
In general you should take guidance from the API documentation. For example the Activity.onCreate() explicitly states that:
This method must be called from the main thread of your app.
For the example you gave Activity.setRequestedOrientation() there is no explicit statement that the method should be called on a particular thread. Usually if threading is of concern the documentation will state that.
If you would prefer certainty then you called also call upon Activity.runOnUiThread()
The Android Developers site states that two rules must be followed when working in the UI thread, i.e.,
Do not block the UI thread
Do not access the Android UI toolkit from outside the UI thread*
Does this mean that I can access variables in the UI thread from within a worker thread, i.e., not UI toolkit?
If so, do any special considerations need to be given if the variable is being continually updated, e.g., from a SensorEventListener. Thanks.
Does this mean that I can access variables in the UI thread from within a worker thread, i.e., not UI toolkit?
Yes, as long as they are declared as member variables then you can access them. You can even access values in UI elements such as using getText() on a TextView you just can't update any of the UI elements.
do any special considerations need to be given if the variable is being continually updated,
If they are being updated then you may want to have a way of syncing the variables. A good way to do this would be to use an AsyncTask and update the variable in onPostExecute().
If you aren't familiar with using AsyncTask, make sure you look through the Docs several times and understand them.
No, you can't access them outside the UI thread. Very few UI elements can be accessed from a non-UI thread with one being ProgressBar.
You can access UI elements in a separate thread but you cannot update them
The only way you can update a UI element in a non-UI thread would be to have a callback to the UI thread in the separate thread using runOnUiThread or using a Handler aside from that you cannot make changes to a UI element in a separate thread
Variables are not to be accessed outside the UiThread. If you'd like to make modifications from outside the UiThread use :
Activity.runOnUiThread(Runnable)
Some "post" method that stores modifications waiting for the UiThread to treat them. You can use a BlockingQueue for example. Have a look at java.util.concurrent package
In some very rare cases the modification of a variable outside the UiThread cannot produce errors in which case it is safe to access it out of the UiThread. In other cases variables should be private, and attempts to access them outside the UiThread should raise IllegalStateException or something like that.
Hopefully someone can explain this to me or point me to a resource I can read to learn more. I am building an app that uses a ListView and a custom list adapter that I modeled off one of the many tutorials available online such as this one:
http://www.softwarepassion.com/android-series-custom-listview-items-and-adapters/
It worked fine. However, every example of how to do this runs the process of building the list of objects to be displayed and collecting the required data on separate threads.
I want to know why/couldn't you just put everything into onCreate? I can't see a reason why you would need separate threads to make this happen. Is there some general form/standard for when/what must me run on certain threads?
The Android docs on this are very good, as with most things.
The upshot is: the UI should always be responsive. So if you have some operation that will take enough time that the user will notice, you might want to consider not running it in the UI thread. Some common examples are network IO and database accesses. It's something of a case-by-case basis though, so you have to make the call for yourself a bit.
Well, if building the list of objects is not a relatively short process, doing it in onCreate() would be blocking/slowing the main thread. If you use a separate thread, it will allow the android os to load all of the UI elements while you are waiting for the list to be populated. Then when the list of objects is ready, you can instantly populate the already initialized UI, as opposed to waiting to initialize the UI until after the list of objects is built. It ensures that your application will always be responsive for the user.
Because you only have 0.5 sec to execute onCreate — after which the dreaded ADN (application not responding) error message is displayed. So unless your list view is super simple you won't make it it in time. And even if your list view is super simple it is better to learn it the proper way.
BTW: I don't even use threads, I use one or more Services to do all the work. Even more difficult to implement but more robust and responsive as well.
The reason you don't do things in onCreate or on the UI thread is for responsiveness. If your app takes too long to process, the user gets shown an App Not Responding dialog.
my teacher once said: every software can be written in a single (big) for loop.
And if you think: it can be... maybe at NDK level.
Some SDK developers wanted to make the software developers tasks easier and that's, why exists the SDK's and frameworks.
Unless you don't need anything from multitasking you should use single threading.
Sometimes there are time limitations, sometimes UI/background/networking limitations and need to do stuff in diff threads.
If you see source code of Asyntask and Handler, you will see their code purely in Java. (of course, there some exceptions, but that is not an important point).
Why does it mean ? It means no magic in Asyntask or Handler. They just make your job easier as a developer.
For example: If ProgramA calls methodA(), methodA() would run in a different thread with ProgramA.You can easily test by:
Thread t = Thread.currentThread();
int id = t.getId();
And why you should use new thread ? You can google for it. Many many reasons.
So, what is the difference ?
AsyncTask and Handler are written in Java (internally use a Thread), so everything you can do with Handler or AsyncTask, you can achieve using a Thread too.
What Handler and AsyncTask really help you with?
The most obvious reason is communication between caller thread and worker thread. (Caller Thread: A thread which calls the Worker Thread to perform some task.A Caller Thread may not be the UI Thread always). And, of course, you can communicate between two thread by other ways, but there are many disadvantages, for eg: Main thread isn't thread-safe (in most of time), in other words, DANGEROUS.
That is why you should use Handler and AsyncTask. They do most of the work for you, you just need to know what methods to override.
Difference Handler and AsyncTask: Use AsyncTask when Caller thread is a UI Thread. This is what android document says:
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
I want to emphasize on two points:
1) Easy use of the UI thread (so, use when caller thread is UI Thread).
2) No need to manipulate handlers. (means: You can use Handler instead of AsyncTask, but AsyncTask is an easier option).
There are many things in this post I haven't said yet, for example: what is UI Thread, of why it easier. You must know some method behind each kind and use it, you will completely understand why..
#: when you read Android document, you will see:
Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue
They may seem strange at first.Just understand that, each thread has each message queue. (like a To do List), and thread will take each message and do it until message queue emty. (Ah, maybe like you finish your work and go to bed). So, when Handler communicates, it just gives a message to caller thread and it will wait to process. (sophiscate ? but you just know that, Handler can communicate with caller thread in safe-way)
Quoting the Android developer guide found here here its says
Additionally, the Andoid UI toolkit is not thread-safe. So, you must
not manipulate your UI from a worker thread—you must do all
manipulation to your user interface from the UI thread
What does it mean that the widget's is not thread safe ? What causes the application to crash when we change the name of a Button off the UI Thread. I understand there is a event queue for the UI thread, but how does a separate thread cause issues with this queue ? I tried looking around, and everywhere it says you cannot do it, but no reason why ?
When the documentation says that the UI toolkit is not thread-safe, this means that the UI toolkit is written in such a way that it assumes that all access to UI objects is made from a single thread. By making this assumption, the implementers of the UI toolkit can make unsynchronized access to all the UI objects without fear of data corruption. This makes the UI toolkit easier to implement, easier to test, and improves the performance of the UI toolkit (because it does not need to lock objects before manipulating them).
The UI toolkit is designed to run ONLY on the main thread (otherwise known as the "UI thread"). If you now access UI components from another thread, you run the risk of corrupting the UI toolkit's objects. To ensure that you don't do that, the UI toolkit designers do 2 things:
They write in the documentation that you aren't supposed to access the UI toolkit from outside the main thread
Some (but not all) methods of the UI toolkit check to see if you are making access from outside of the main thread and throw exceptions in such conditions
However, this doesn't forcibly prevent you from accessing the UI toolkit from another thread. In fact, you can probably change the text on a button from another thread without any bad side-effects. That said, you still shouldn't do it. Because in some cases you will cause crashes, in some cases you will find that the changes you make to the UI just get overwritten or ignored, etc.
I hope this makes sense.
The Qt doc says,
As mentioned, each program has one thread when it is started. This
thread is called the "main thread" (also known as the "GUI thread" in
Qt applications). The Qt GUI must run in this thread.
The Android doc says,
Like activities and the other components, services run in the main
thread of the application process
And iOS,
It is strongly recommended not to update UI controls etc from a
background thread (e.g. a timer, comms etc). This can be the cause of
crashes which are sometimes very hard to identify. Instead use these
to force code to be executed on the UI thread (which is always the
“main” thread).
Why does they use a single threaded model to update UI ?
The short answer is, it's the only reasonable way to ensure that the display is not corrupted.
The long answer is that allowing multiple threads to update the UI results in deadlocks, race conditions, and all sorts of trouble. This was the painful lesson taught by Java's AWT (among other UI systems) that allows multiple threads to touch the UI. See, for instance, Multithreaded toolkits: A failed dream?. That post refers (via dead links) to Why Threads Are A Bad Idea and Threadaches.
iOS and Android force you to work with UI only from main thread. The reason is the same as a shared object, thread safe[About]... in multithread environment
Android example error
FATAL EXCEPTION: Thread-19449
E/AndroidRuntime: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views
iOS example error
This application is modifying the autolayout engine from a background thread" error?