Http://www.cnblogs.com/xitang/archive/2011/09/24/2189460.html
Processes and Threads
The name of the translator: the Prawn
Translator Weibo: Http://weibo.com/popapa
Version: Android 3.2 r1
Original
Http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html
Quick View · By default, each application runs in its own process, and all components in the application run in it. · All slow, blocking operations in the activity should run in the newly created thread to avoid slowing down the user interface. In this article Process The life cycle of a process Thread Worker threads Thread-Safe methods Inter-process communication
|
Processes and Threads
If an application component is started for the first time and no other components are running on the application, the Android system creates a Linux process for the application that contains a single thread. By default, all components of the same application run in the same process and line thread (called "main" main thread). If the process of the application already exists when the component is started (because other components of the application are already running), this component will start running in the existing processes and threads. However, you can specify that the component is running in another process, or you can create additional threads for any process.
This article discusses how processes and threads work in Android applications.
Process
By default, all components within the same application are running in the same process, and most applications will not change it. However, if you need to specify the process to which a particular component belongs, you can use the manifest file to achieve the purpose.
Each component element in the manifest file--<activity>, <service>, <receiver>, and <provider>--all support defining android:process properties that specifies the process that the component runs. Setting this property allows each component to run in its own process, or several components to share a process while other components run on separate processes. Setting this property also allows components of different applications to run in the same process-implementing multiple applications that share the same Linux User ID and give the same permissions.
The <application> element also supports the Android:process property, which specifies the default process for all components.
If there is not enough memory, and other processes that provide more emergency services to users require more memory, Android may decide to close a process . The application components that are running in this process are also destroyed. When you need to work again, a process is recreated for those components.
When deciding which process to close, the Android system weighs how important they are relative to the user. For example, compared to a process with visible activity, it is more likely to close an activity that is already invisible on the screen. That is, whether to terminate a process depends on the state of the component running in this process. The decision rules for terminating the process are discussed in the following sections. (Note: The shutdown level of a process, defined by the strongest level in the process.) If there is activity and service in the process, then the level of the process is service. )
The life cycle of a process
The Android system tries to keep the application process as long as possible, but in order to create new or run more important processes, it is always necessary to purge obsolete processes to reclaim memory. In order to decide which process to keep or terminate, each process is zoned into a hierarchy of importance, depending on the components running within the process and the state of those components. The least important process is first cleared, then the next lowest, and so on, which is necessary to reclaim system resources.
The importance hierarchy has 5 levels, and the following list lists the various processes by importance (the first type of process is the most important and the last one is terminated):
1. Foreground Process
The process that the user must have for the current operation. A process is considered to be in the foreground when either of the following conditions is true:
o the activity in which the user is interacting (the Onresume () method of the Activity object has been called).
o It runs service services that are bound by activity that is interacting with the user.
o The service--service, which runs the "foreground" service, is called in Startforeground () mode.
o Service services that are running a lifecycle callback method (OnCreate (), OnStart (), or OnDestroy ()).
o The broadcastreceiver that is running the OnReceive () method is being executed.
In general, the foreground processes are few at any point, and only as a last-minute strategy-when memory is not enough to sustain them at the same time-will be terminated. Typically, the device has reached the point where the memory paging state is paging, terminating some foreground processes to ensure a timely response from the user interface.
2. Visible Processes
A process that does not have a foreground component, but still affects what the user sees on the screen. A process is considered visible when either of the following conditions is true:
o The activity that is not in the foreground is running, but the user is still visible to the activity (the OnPause () method is called). This can happen in the following situations: The foreground activity opens a dialog box, and the previous activity is allowed to appear behind.
o Service services that run with the visible (or foreground) activity bindings.
The visible process is considered a very important process and will not be terminated unless all foreground processes are not maintained at the same time.
3. Service Process
This process runs a service started by the StartService () method, and it does not upgrade to the above two levels. Although service processes are not directly associated with what the user sees, they typically perform actions that are of interest to the user (such as playing music in the background or downloading data from the network). Therefore, the system keeps the service process running unless the memory is insufficient to maintain all foreground and visible processes running concurrently.
4. Background Process
Contains the process of the current user's invisible activity (The OnStop () method of the Activity object has been called). These processes have no direct impact on the user experience, and the system may terminate them at any time to reclaim memory for use by foreground processes, visible processes, and service processes. There are often many background processes running, so they are stored in an LRU(least Recently used) list to ensure that the last activity that was recently used by the user is terminated. If an activity correctly implements the lifecycle method and saves the current state, terminating such a process does not have a visible impact on the user experience. Because the activity restores all visible states when the user returns. For more information about save and restore status, see the activities documentation.
5. Empty Process
Processes that do not contain any active application components. The only purpose of preserving this process is to use it as a cache to improve the startup time of the next component running in this process. In order to balance the overall system resources between the process cache and the kernel cache, the system often terminates this process.
Depending on the importance of the current active component in the process,Android evaluates the process to a level that is as high as possible . For example, if a process is running a service and a user-visible activity, the process is evaluated as a visible process, not a service process.
In addition, the level of one process may be enhanced by the dependency of other processes-the process level that provides services to other processes is never lower than the process using the service. For example, if the content provider in a process serves the client in process B, or if the service in process A is called by a component in process B, the a process is considered to be at least as important as process B.
Because the process level at which the service is running is higher than the background activity process, if the activity needs to start a long-running operation, it is better to start a service server for it than simply to create a worker thread- This is especially true if the operation time is longer than the activity itself. For example, an activity that uploads a picture to a Web site should create a service to execute it, even if the user leaves the activity and the upload will continue to run in the background. Regardless of what happens to the activity, using the service guarantees that the operation has at least the priority of the service process. Similarly, the broadcast receiver in the previous article, broadcast receiver, also uses services rather than threads to handle time-consuming tasks.
(Personal understanding: Starting a service and starting a thread in activity is pretty much the same.) Why should I start a thread in the service? This is because the service is shut down to ensure continuous operation. Activity is easy to shut down. )
Thread
When the application starts, a main thread called "main" is created for it. The main thread is important because it is responsible for distributing events to the appropriate user interface widget--including screen drawing events. It is also a thread that the application interacts with the Android UI component package (from the Android.widget and Android.view packages). Therefore, the main thread is sometimes called the UI thread.
The system does not create separate threads for each instance of the component. All components running in the same process are instantiated in the UI thread, and system calls to each component are also distributed by the UI thread. Therefore, methods that respond to system callbacks, such as onkeydown () or lifecycle callback methods that report user actions, are always running in the UI thread.
For example, when a user touches a button on the screen, the application's UI thread sends the touch event to Widget,widget first by placing itself in the pressed state, and then sending a request to the event queue where the display area is invalidated (invalidate). The UI thread pulls this request out of the queue and notifies the widget to redraw itself.
If an application needs to perform heavy tasks while interacting with the user, single-threaded mode can lead to poor performance unless the application is executed at exactly the right time. If the UI thread needs to handle everything, those long-consuming operations-such as accessing the network or querying the database-will block the entire UI (thread). Once the thread is blocked, all events cannot be distributed, including screen drawing events. From the user's point of view, the application looks like it hangs. Even worse, if the UI thread is blocked for more than a certain amount of time (currently about 5 seconds), the user will be prompted with the hateful "Application Not Responding" (ANR) dialog box. If the user is dissatisfied, he may decide to quit and delete the application.
Additionally, the UI component package for Andoid is not thread-safe. Therefore, operating from a worker thread is not allowed ui--can only manipulate the user interface from the UI thread. As a result, Andoid's single-threaded mode must comply with two rules:
1. Do not block the UI thread.
2. Do not access the Andoid UI component package outside of the UI thread.
Worker threads
Based on the description of the single-threaded pattern above, the key to ensuring the responsiveness of the program interface is that the UI thread cannot be blocked. If the operation does not complete quickly, you should let them run in a separate thread ("background" or "work" thread).
For example, the following code that responds to a mouse click implements the download of the picture in a separate thread and displays it in ImageView:
public void OnClick (View v) {
New Thread (New Runnable () {
public void Run () {
Bitmap B = loadimagefromnetwork ("Http://example.com/image.png");
Mimageview.setimagebitmap (b);
}
}). Start ();
}
At first glance, this code seems to work well, because a new thread is created to handle the operation of accessing the network. But it violates the second rule of single-threaded mode: do not access the Andoid UI component package outside the UI thread-The above example modifies imageview in the work line thread instead of the UI threads. This can lead to ambiguous and unforeseen consequences, and it is also difficult and time-consuming to track this situation.
To address these issues, Android provides several ways to access the UI thread from other threads. Here are a few ways to help solve the problem:
· Activity.runonuithread (Runnable)
· View.post (Runnable)
· View.postdelayed (Runnable, long)
For example, you can use the View.post (Runnable) method to fix the above code:
public void OnClick (View v) {
New Thread (New Runnable () {
public void Run () {
Final Bitmap Bitmap = loadimagefromnetwork ("Http://example.com/image.png");
Mimageview.post (New Runnable () {
public void Run () {
Mimageview.setimagebitmap (bitmap);
}
});
}
}). Start ();
}
The execution of the above code is now thread-safe: Network-related operations are done in a separate thread, and ImageView is manipulated in the UI thread.
However, as operations become more complex, such code can become complex and difficult to maintain. In order to use a worker thread for more complex interaction processing, consider using handler in a worker thread to handle messages distributed by the UI thread. Of course, the best solution might be to inherit the asynchronous task class Asynctask, which simplifies some of the actions of worker threads and UI interactions.
Using Asynchronous tasks
The asynchronous task Asynctask allows the user interface to be manipulated asynchronously. It blocks the worker threads before rendering the results in the UI thread, which does not require human intervention on threads and handler.
To use an asynchronous task, you must inherit the Asynctask class and implement the Doinbackground () callback method, which will run in a pool of background threads. To update the UI, implement the OnPostExecute () method to distribute the results returned by Doinbackground (), because this method runs in the UI thread, so you can safely update the UI. You can then invoke execute () in the UI thread to perform the task.
For example, you can use Asynctask to implement the above example:
public void OnClick (View v) {
New Downloadimagetask (). Execute ("Http://example.com/image.png");
}
Private class Downloadimagetask extends Asynctask<string, Void, bitmap> {
/** The system calls this to perform work in a worker thread and
* delivers it the parameters given to Asynctask.execute () */
Protected Bitmap doinbackground (String ... urls) {
Return Loadimagefromnetwork (Urls[0]);
}
/** The system calls the perform work in the UI thread and delivers
* The result from doinbackground () */
protected void OnPostExecute (Bitmap result) {
Mimageview.setimagebitmap (result);
}
}
The UI is now secure, and the code is simplified because the task is decomposed into parts that are completed within the worker thread and within the UI thread.
To fully understand the use of this class, you must read the Asynctask reference documentation. Here's an overview of how it works:
· You can use generics to specify the types of parameters, progress values, and task final values.
· The Doinbackground () method in the worker thread is executed automatically.
· Both the OnPreExecute (), OnPostExecute (), and Onprogressupdate () methods are called in the UI thread.
· The return value of Doinbackground () is passed to OnPostExecute ().
· At any point within doinbackground (), you can call Publishprogress () to execute onprogressupdate () in the UI thread.
· You can cancel a task at any time, in any thread.
Note: Another problem you may encounter when working with worker threads is that the activity restarts unexpectedly due to changes in the running configuration (such as a user changing the screen orientation), which may destroy the worker thread. To learn how to maintain task execution in this case, and how to properly cancel a task when the activity is destroyed, see the source code for the shelves routine.
Thread-Safe methods
In some cases, methods may be called from more than one thread, so these methods must be written as thread-safe.
This is a matter of course for methods that can be called remotely-such as the binding service (bound services). If the invocation of the method implemented by IBinder originates inside the process where IBinder is located, then this method is executed in the caller's thread. However, if the call originated in another process, then this method would run on a thread approached selected in the pool of threads (rather than in the UI thread running on the process), which is maintained by the system and is in the same process as the IBinder. For example, even if the Onbind () method of a service is called from the UI thread of the process in which the service is located, a method object that implements the Onbind () (for example, a subclass of the RPC method) will still be called from a thread in the thread pool. Because a service can have more than one client, multiple thread pools can be associated with the same IBinder method at the same time. Therefore, the IBinder method must be implemented as thread-safe.
Similarly, content providers (provider) can receive data requests from other processes as well. Although the Contentresolver class, the ContentProvider class hides the details of interprocess communication management, the method that responds to the request in ContentProvider--query (), insert (), delete (), update () and GetType () method--is called from the thread pool of the process where the ContentProvider is located, not the UI thread of the process. Because these methods may be called concurrently from many threads, they must also be implemented as thread-safe.
Inter-process communication
Android uses remote procedure calls (Remotes procedure Call,rpc) to provide an interprocess communication (IPC) mechanism through which methods that are invoked by activity or other application components are executed remotely (in other processes). All results are returned to the caller. This requires that the method invocation and its data be decomposed to a level understandable to the operating system and transferred from the local process and address space to the remote process and address space, and then reassembled and executed in the remote process. The return value after execution is transmitted back in reverse. Android provides all the code needed to execute an IPC transaction, so just focus on defining and implementing RPC programming interfaces.
To execute the IPC, the application must be bound to the service with Bindservice (). For more information, see the Service Services Development Guide.
Processes and Threads