To clarify: The application’s main thread is not always the UI thread.
For example: If an activity is stopped, the onStop() is invoked, hence the UI thread is taken away from that activity and moved to another activity within the same or a different application.
However, it doesn’t mean that this application is no longer active. Furthermore, if there is a (started) service running in the background, it may continue for a while, until it terminates or the Android OS terminates it due to lack of resources.
Who runs this service during that time? Who triggers the onStop() or the onDestroy()? It’s the application’s main thread doing that.
The UI thread is a kind of Singleton. It can be used by only one visible activity at a time. Either the application’s main thread is joined/attached to the UI thread or another one gets it. However this does not mean, that the application doesn’t have a main thread of its own.
This behavior comes from the Linux\Unix foundation of the Android System. What most developers are not aware of: The application is a “user” within the Linux\Unix OS.
Whenever an application is invoked, it is similar to a user logging into the system. In the application’s case, the user id is the unique application id, while no password is required. The new logged in “user” (i.e. Android application) gets a process and resources such as an instance of the Java Virtual Machine. The process is dedicated to this user and the resources including file system quota, file descriptors and handlers allow it to communicate with the OS.
The android application’s main thread is the root thread that is created from the process the Android OS hands over to that application. Any new threads created in this application will always return to the main thread.
One of system resources that the application’s main thread can gain access to, is the UI thread. Hence the application can request the main thread, however the request may be refused (or granted). An example: In case the application process exceeds it’s allowed memory allocation size, the Android OS may decide to refuse access to the UI thread and even destroy the application and terminate the process.
It is possible to define more than on process for an application (Unix process fork) via definition in the AndroidManifest.xml. However, bear in mind, that the resources assigned to each process will be different, i.e. each process will have its own VM, hence objects maintained in the different processes will not be able to share information via the same JVM heap.