Basic concepts of processes and threads
When an application starts to run its first component, Android starts a Linux Process for it and executes a single thread in it. By default, all components of the application are run in the thread of this process. However, you can also schedule components to run in other processes and derive other threads from any process.
Processes in Android
The process where the component runs is controlled by the manifest file. Component elements -- <activity>, <service>, <javaser>, and <provider> -- both have a process attribute to specify the process in which the component should run. These attributes can be set to make each component run within its own process, or some components share a process, while other components do not. They can also be set to allow components of different applications to run in a process-share the components of the application with the same Linux User ID and grant the same permissions. The <application> element also has a process attribute to set the default values for all components.
All component instances are located in the main thread of a specific process, and system calls to these components will also be distributed by that thread. Generally, no threads are created for each instance. Therefore, some methods always run in the main thread of the process. These methods include reporting user actions and lifecycle notifications such as View. onKeyDown. This means that when a component is called by the system, it should not perform long or blocked operations, such as network-related operations or cyclic computing ), this will block the running of other components that are also in this process. As described in the following thread section, a separate thread is derived for these long operations for processing.
When the available memory is insufficient and another process serving the user needs more memory, Android may sometimes close a process. The applications running in this process are also destroyed. When a task needs to be processed again, the process is re-created for these components.
When deciding which process to end, Android will measure their relative importance to users. For example, a process that is invisible to users is more likely to shut down a process that is no longer visible to users. It can also be said that deciding whether to shut down a process is mainly based on the status of the component running in that process.
Threads in Android
Although you can restrict your application to a single process, sometimes you still need to derive a thread to process Background tasks. Because the user interface must respond to user operations in a very timely manner, the thread controlling activity should not be used to process time-consuming operations such as network downloads. All tasks that cannot be completed instantly should be arranged in different threads.
The thread is created as a standard JavaThread object in the code. Android provides many classes to facilitate thread management: logoff is used to run a message loop in a thread, Handler is used to process messages, and HandlerThread is used to enable a thread using a message loop.
RPC: Remote Procedure Call
Android has a lightweight Remote Procedure Call RPC) mechanism: Call A method locally, but in other remote processes) for processing, and then return the result to the caller. This separates method calls and their ancillary data in a way that the system can understand, and transfers it from the local process and local address space to the remote process and remote address space, and reassemble and respond to the call. The returned results are transmitted in the opposite direction. Android provides all the code required to complete these tasks, so that you can concentrate on implementing the RPC interface itself.
The RPC interface can only contain methods. Even if no return value is returned, all methods still execute local method blocking in synchronous mode until the remote method ends ).
To put it simply, this mechanism works like this: at the beginning, you declare an RPC interface that you want to implement using a simple IDL Interface language. Then, use the aidl tool to generate a Java interface definition for this declaration. This definition must be visible to both local and remote processes. It contains two internal classes. The internal class manages all the code required to call the remote method of the interface declared by IDL. Both internal classes implement the IBinder interface. One is used internally by the system, and some code can be ignored; the other is called Stub, which extends the Binder class. In addition to implementing the internal code of the IPC call, it also includes the declaration of methods in the declared RPC interface. Generally, a remote process is managed by a service because the service can notify the system about the process and its connection to other processes ). It contains the interface file generated by the aidl tool and the Stub subclass that implements the RPC method. The client only needs to include the interface files generated by the aidl tool.
The following describes how to establish a connection between a service and its client. For more details about RPC mechanisms, see the distributed system book by nanny Tani, there are very detailed and brilliant discussions:
1) The service client is located locally.) onServiceConnected () and onServiceDisconnected () methods should be implemented. In this way, when the connection to the remote service is successfully established or disconnected, they will receive a notification. In this way, they can call bindService () to set the connection.
2) The Service should implement the onBind () method to accept or reject the connection. It depends on the intentintent it receives and passes it to bindService ()). If the connection is accepted, it returns an instance of the Stub subclass.
3) if the service accepts the connection, Android will call the onServiceConnected () method of the client and pass it to an IBinder object, which is the proxy of the Stub subclass managed by the Service. Through this proxy, the client can call the remote service.
Measure the test taker's knowledge about thread security.
In some cases, the methods you implement may be called by more than one thread, so they must be written as thread-safe.
For methods that can be remotely called in the RPC mechanism discussed above, this must be considered first. If the call to the method implemented in an IBinder object comes from the process of the IBinder object, this method will be executed in the caller's thread. However, if this call comes from other processes, this method will run in the thread selected in a thread pool, which is managed by Android, and it exists in the same process as IBinder. This method is not executed in the main thread of the process. Conversely, the onBind () method of a service should be called by the main thread of the service process, and the object returned by onBind () is implemented, for example, a subclass of Stub that implements the RPC method) will be called by the thread in the pool. Because the service can have more than one client, and at the same time, there will also be threads in multiple pools calling the same IBinder method. Therefore, the IBinder method must be thread-safe.
Similarly, a content provider can accept request data from other processes. Although the ContentResolver and ContentProvider classes hide the management details of the interactive communication process, ContentProvider will be composed of query (), insert (), delete (), update () and getType () methods are provided by the thread pool included in the process of the content provider, rather than the main thread of the process. Therefore, these methods that may be called by many threads at the same time must also be implemented as thread-safe.