Detailed Android process and thread _android

Source: Internet
Author: User
Tags documentation hosting

It's written in front of you.

An android application is a Linux process in which each application runs in its own process, with no distractions and more security.

One application corresponds to a main thread, which is usually called the UI thread, and Android adheres to the single-threaded model, so the UI operation is not thread safe and must be performed in the UI thread.

This article is the Official document translation, the original link: https://developer.android.com/guide/components/processes-and-threads.html

Overview

When an application component is started and the application does not run any other components, the Android system uses a single thread of execution to start a new Linux process for the application. By default, all components of the same application run in the same process and thread, called the master thread. If an application component is started and the application already has a process (because there are other components of the application), the component starts within the process and uses the same execution thread. However, you can schedule other components in the application to run in a separate process and create additional threads for any process.

This document describes how processes and threads work in Android applications.

First, the process

By default, all components of the same application run in the same process, and most applications do not change that. However, if you find that you need to control which process a component belongs to, you can do so in the manifest file.

Manifest file entries for various component elements —、、 and-support the Android:process property, which specifies which process the component should run. You can set this property so that each component runs in its own process, or that some components share a process, while others are not shared. In addition, you can set up android:process to enable components of different applications to run in the same process, provided that these applications share the same Linux user ID and sign with the same certificate.

In addition, the element supports the Android:process property to set the default values that apply to all components.

If there is not enough memory and other processes that provide more emergency services to the user require memory, Android may decide to close a process at some point. The application components that run in the terminated process are also destroyed. When these components need to be run again, the system restarts the process for them.

When deciding which process to terminate, the Android system will weigh their relative importance to the user. For example, it is more likely to shut down an activity process that is no longer visible on the managed screen, relative to the process of hosting a visible activity. Therefore, the decision whether to terminate a process depends on the state of the components that are running in the process. Below, we describe the rules used to decide how to terminate a process.

Process life cycle

The Android system will keep the application process as long as possible, but in order to create a new process or run more important processes, you end up needing to clean up the old process to reclaim memory. To determine which processes are retained or terminated, each process is placed in the importance hierarchy based on the components that are running in the process and the state of those components. When necessary, the system first eliminates the least important processes, then the processes that are less important, and so on, to reclaim system resources.

The hierarchy of importance has a total of 5 levels. The following list lists the types of processes that are important (the first process is the most important and will be the last terminated process):

1. Foreground process

The process required by the user's current operation. If a process satisfies any of the following conditions, it is considered a foreground process:

Activity that the managed user is interacting (the Onresume () method of the invoked activity)
Hosting a Service that is bound to an activity that the user is interacting with
Managed services that are running in the foreground (service called Startforeground ())
Managed Service that is performing a lifecycle callback (OnCreate (), OnStart (), or OnDestroy ())
managed to execute its onreceive () method Broadcastreceiver

Typically, there are few foreground processes at any given time. The system will terminate them only if they are not enough to support them and continue to run at the same time. At this point, the device often reaches the memory paging state, so you need to terminate some of the foreground processes to ensure that the user interface is responding properly.

2. Visible process

A process that does not have any foreground components but still affects what the user sees on the screen. If a process satisfies any of the following conditions, it is considered a visible process:

Hosts an activity that is not in the foreground but is still visible to the user (its OnPause () method has been called). For example, this can happen if the foreground activity starts a dialog box that allows the previous activity to be displayed thereafter
managed to bind to visible (or foreground) activity's Service
Visible processes are considered extremely important processes that are not terminated unless they must be terminated in order to maintain all foreground processes running at the same time.

3. Service Process

Running a process that has started with the StartService () method and is not part of the above two higher class processes. Although service processes are not directly associated with what users see, they typically perform actions that are of interest to users (for example, 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 keep all foreground and visible processes running at the same time.

4. Background process

A process that contains an activity that is not currently visible to the user (the OnStop () method of the activity that has been invoked). 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, or service processes. There are usually many background processes running, so they are saved in the LRU (least recently used) list to ensure that the last process that contains the activity that the user has recently viewed is terminated. If an activity implements the lifecycle method correctly and saves its current state, terminating its process will not have a noticeable impact on the user experience because the activity restores all its visible state when the user navigates back to the activity. For information about saving and restoring status, see the activity documentation.

5. Empty process

A process that does not contain any active application components. The only purpose of keeping this process is to use it as a cache to shorten the startup time that is required to run the component next. To keep the overall system resources balanced between the process cache and the underlying kernel cache, these processes are often terminated by the system.

Depending on the level of importance of the currently active component in the process, Android evaluates the process to the highest level it can reach. For example, if a process hosts services and visible activity, the process is evaluated as a visible process, not a service process.

In addition, the level of one process may be increased by the reliance of other processes on it, that is, the process that serves another process is never lower than the process it serves. For example, if the content provider in process a provides services to clients in process B, or if the services in process A are bound to components in process B, process A is always considered to be at least as important as process B.

Because the process that runs the service is higher than the process of managed background activity, the activity that initiates the long-running operation is best to start the service for the operation, rather than simply creating the worker thread, especially if the operation is likely to last longer than the activity. For example, an activity that is uploading a picture to a Web site should start the service to perform an upload, so that the upload can continue in the background, even if the user exits the action. Using a service ensures that the operation has at least the service process priority, regardless of the activity. Similarly, broadcast receivers should use services rather than simply putting lengthy operations into threads.

Second, the thread

When the application starts, the system creates an execution thread named "Main thread" for the application. This thread is important because it is responsible for assigning events to the appropriate user interface gadget, including drawing events. In addition, it is a thread that interacts with the Android UI Toolkit component (components from the Android.widget and Android.view packages). Therefore, the main thread is sometimes called the UI thread.

The system will never create a separate thread for each component instance. All components running in the same process are instantiated in the UI thread, and system calls to each component are assigned by that thread. Therefore, a method that responds to a system callback (for example, the OnKeyDown () or lifecycle callback method that reports a user action) is always running in the process's UI thread.

For example, when a user touches a button on the screen, the applied UI thread assigns the touch event to the gadget, which in turn sets its pressed state and publishes the invalid request to the event queue. The UI thread cancels the request from the queue and notifies the gadget that it should redraw itself.

This single-threaded pattern can lead to poor performance when the application performs heavy tasks in response to user interaction unless the application is properly implemented. In particular, if the UI thread needs to handle all tasks, performing lengthy operations (for example, network access or database queries) will block the entire UI. Once a thread is blocked, no events can be dispatched, including drawing events. From the user's point of view, the application appears to be suspended. Even worse, if the UI thread is blocked for more than a few seconds (currently about 5 seconds), the user will see a boring "Apply no response" (ANR) dialog box. If the user is dissatisfied, they may decide to exit and uninstall the application.

In addition, the Android UI Toolkit is not a thread-safe tool pack. Therefore, you must not manipulate the UI through a worker thread, but only manipulate the user interface through the UI thread. As a result, Android's single-threaded mode must adhere to two rules:

1, do not block the UI thread
2. Don't access the Android UI Toolkit outside of the UI thread

Worker threads

Depending on the single-threaded pattern described above, the key to ensuring the responsiveness of the UI is that the UI thread cannot be blocked. If the actions you perform cannot be completed quickly, make sure that they run in a separate thread (background or work thread).

For example, the following code shows a hit listener downloading an image from a separate thread and displaying 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 be working well because it creates a new thread to handle network operations. However, it violates the second rule of single-threaded mode: Do not access the Android UI Toolkit outside of the UI thread-this example modifies the ImageView from the worker thread instead of the UI threads. This may lead to ambiguous and unpredictable behavior, but it can be difficult and time-consuming to track this trip.

To address this issue, Android offers several ways to access the UI thread from other threads. Several useful methods are listed below:

Activity.runonuithread (Runnable)
View.post (Runnable)
View.postdelayed (Runnable, long)
For example, you can fix the above code by using the View.post (Runnable) method:

public void OnClick (View v) {
  new Thread (new Runnable () {public
    void run () {
      final Bitmap Bitmap = LOADIMAGEF Romnetwork ("Http://example.com/image.png");
      Mimageview.post (New Runnable () {public
        void run () {
          mimageview.setimagebitmap (bitmap);}}
      );
  }). Start ();
}

The above implementation is now thread-safe: Complete network operations in a separate thread and manipulate ImageView in the UI thread.

However, as operations become more complex, such code can become complex and difficult to maintain. To handle more complex interactions through a worker thread, consider using Handler to process messages from the UI thread in a worker thread. Of course, the best solution might be to extend the Asynctask class, which simplifies the work-thread task that is required to interact with the UI.

Using Asynctask

Asynctask allows asynchronous operations to be performed on the user interface. It blocks the operation in the worker thread first, and then publishes the results in the UI thread without having to deal with the line threads/or handlers yourself.

To use it, you must create a Asynctask subclass and implement the Doinbackground () callback method, which will run in the background thread pool. To update the UI, you must implement OnPostExecute () to pass the results returned by Doinbackground () and run in the UI thread so that you can safely update the UI. Later, you can run the task by calling execute () from the UI thread.

For example, you can use Asynctask to implement the above example in the following ways:

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 W Ork in a worker thread and
   * delivers it the parameters given to Asynctask.execute () * * Protected Bitmap
  Round (String ... URLs) {return
    loadimagefromnetwork (urls[0]);

  /** The system calls this to perform work the UI thread and delivers * The result from
   doinbackground () * *
  PR otected void OnPostExecute (Bitmap result) {
    mimageview.setimagebitmap (result);
  }
}

The UI is now secure and the code is simplified because the task is broken down into two parts: part should be done within the worker thread and the other part should be done within the UI thread.

The following is a brief overview of how Asynctask works, but to get a complete picture of how to use this class, you should read the Asynctask reference documentation:

You can use generics to specify parameter types, progress values, and task final values
Method Doinbackground () is automatically executed on the worker thread
OnPreExecute (), OnPostExecute (), and Onprogressupdate () are called in the UI thread
The value returned by Doinbackground () will be sent to OnPostExecute ()
You can call Publishprogress () at any time in Doinbackground () to execute the onprogressupdate () in the UI thread.
You can cancel a task in any thread at any time

Note: when working with a worker thread, you may experience another problem: a run-time configuration change (for example, a user changing the screen direction) causes an activity to restart unexpectedly, which may destroy the worker thread. To learn how to persist with this reboot and how to cancel the task correctly when the activity is destroyed, see the source code for the Bookshelf sample application.

Thread-Safe methods

In some cases, the methods that you implement may be invoked from multiple threads, so writing these methods must ensure that they meet the requirements of thread safety.

This applies primarily to methods that can be invoked remotely, such as methods in a binding service. If a call to an implemented method in IBinder originates from the same process that is running IBinder, the method executes in the caller's thread. However, if the call originates from another process, the method executes in a thread selected from the thread pool (rather than in the process's UI thread), and the thread pool is maintained by the system in the same process as the IBinder. For example, even if the Onbind () method of a service is invoked from the UI thread of the service process, the method implemented in the object returned by Onbind (for example, the subclass that implements the RPC method) is still invoked from a thread in the thread pool. Because a service can have multiple clients, there may be multiple pool threads using the same IBinder method at the same time. Therefore, the IBinder method must be implemented as a thread-safe method.

Similarly, a content provider can receive data requests from other processes. Although the Contentresolver and ContentProvider classes hide details about how interprocess communication is managed, the ContentProvider method that responds to these requests (query (), insert (), delete (), update () and the GetType () method) are invoked from the thread pool of the process in which the content provider resides, rather than from the process's UI thread. Because these methods may be invoked at the same time from any number of threads, they must also be implemented as thread-safe methods.

Inter-process communication

Android uses remote procedure call (RPC) to provide an interprocess communication (IPC) mechanism through which methods called by an activity or other application component are executed remotely (in other processes), and all results are returned to the caller. This requires that the method call and its data be decomposed to the extent that the operating system is recognizable 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 is then transmitted back in the opposite direction. Android provides all the code needed to execute these IPC transactions, so you need to focus on defining and implementing RPC programming interfaces.

To perform IPC, you must bind the application to the service using Bindservice (). For more information, please refer to the Service Developer's Guide.

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.