One, foreword

The process survival of the Android system consists of two aspects: 1. Improve the process priority to reduce the probability of process killing. 2. Pull the process alive after it is killed.

Let’s start with process priorities: The Android system tries to keep application processes as long as possible, but in order to create new processes or run more important ones, the old processes will eventually need to be cleared to reclaim memory. To determine which processes to keep or kill, each process is placed in an “importance hierarchy” based on the components that are running in the process and the state of those components. When a process is terminated, some of the less important processes are eliminated first, and so on, to reclaim system resources.

According to the priority of the process, the process can be divided into five levels: Foreground process (Foreground) 2, Visible process (Service Process) 3, Service process (Background process) 4, Background process 5, Empty process (Empty Process) The characteristics of these five processes are described as follows: 1. Foreground Process Essential to the current operation of the user. There are not many foreground processes in existence at any given time. The system terminates them only when there is not enough memory to support them simultaneously. Some examples of foreground processes are: A) owning an Activity that the user is interacting with (onResume has been called) B) owning A Service that is bound to the Activity that the user is interacting with. C, Service foreground (Service is called startForeground) D, Service foreground (onCreate, onStartCommand, or onDestroy) E. BroadcastReceiver with the onReceive method being implemented

A Visible process that does not have any foreground components but still affects what the user sees on the screen. Visible processes are considered extremely important and are not terminated unless necessary to keep all foreground processes running at the same time. Examples of visible processes are: A) having an Activity that is not in the foreground but is still visible to the user (onPause has been called) B) having A Service bound to the visible (or foreground) Activity

Service processes have no direct connection to what the user sees, but they usually perform some action that the user cares about (for example, playing music in the background or downloading data from the network). Therefore, unless there is not enough memory to keep all foreground and visible processes running at the same time, the system will leave the server processes running. Some examples of service processes: A. A service started with startService that does not belong to either of the above two higher levels of processes.

Background processes have no direct impact on the user experience, and the system may terminate them at any time to reclaim memory for foreground, visible, and server processes. There are usually many background processes running, so they appear in the LRU list to ensure that the process containing the Activity the user recently viewed is the last to terminate. If an Activity implements the lifecycle methods correctly and saves its current state, terminating its process will not have a noticeable impact on the user experience because the Activity will restore all visible states when navigated back to the Activity. Some examples of background processes: a. Processes for activities that are not visible to the user (the Activity onStop method has been called)

The Empty process is reserved for the sole purpose of being a cache to reduce the startup time needed to run components in it the next time. In order to balance overall system resources between the process cache and the underlying kernel cache, the system often terminates these processes. Some examples of empty processes: A. Processes that do not contain any active application components.

Specific can refer to the introduction of the official document: developer.android.com/intl/zh-cn/… ] (developer.android.com/intl/zh-cn/…

2. Android process reclamation strategy

Reclaiming memory in Android is done by Lowmemorykiller, which is a reclaiming mechanism that triggers an OOM_ADJ threshold level.

In general, an OOM_ADJ value of 0 indicates foreground processes, and a value greater than 0 indicates background processes or server processes. OOM_ADJ less than 0 indicates a non-Android process (pure Linux process). When Lowmemorykiller retrieves memory, it will kill processes with higher OOM_ADJ priority based on their level, and processes with higher OOM_ADJ priority based on their level.

How to check the process priority (oOM_adj value)? 1. In the command line mode, run adb shell to enter shell mode. 2. The ps command lists information about all running processes. Of course, we can use ps | grep process name (usually for the package name) to filter to get what we want. 3. Obtain the process ID in step 2 and run cat /proc/process ID/oom_adj to obtain the priority of the process. To do this, please refer to the following example:

PS: When checking the process priority, permission denied is returned in the third step. This is because you do not have root permission for the phone, so you need to do this on a root phone or emulator.

Above all, in order to reduce the probability of a process being killed, you need to find a way to increase the priority of the process. Next, we’ll look at several possible solutions in terms of process prioritization.

Iii. Solutions to improve process priority

1. Use Activity to prioritize processes

1.1 Scheme design: Monitor the lock screen and unlock events of the mobile phone, start the Activity with 1 pixel when the screen is locked, and destroy the Activity when the screen is unlocked. The Activity should be designed so that the user is unaware of it. The premise here is that the APP process needs to be in the background. If the APP process is in the foreground, then the process is already a foreground process, and the above approach makes no sense.

With this solution, the priority of a process can be increased from 9 (oOM_adj may vary on different mobile systems) to 0 (foreground process) when the screen is locked. In this way, our APP is not easy to be killed by third-party apps during the lock time.

1.2 Application Scope: Scenario: Third-party applications or system management tools will kill background processes after detecting a screen lock event for a period of time to save power consumption.

Version: Works with all Android versions.

1.3 Specific implementation: Refer to the open source project KeepProcessLive on Github. There is a question about this open source project. When monitoring the lock screen unlocking event of a mobile phone, the lock screen and unlock operation will be monitored for many times, resulting in the invalid scheme sometimes.

2. Use Notification to improve process priority

2.1 Scheme design: Through the setForeground interface of Service in Android, the background Service can be set to foreground Service, so that the priority of the process is increased to 2, so that the priority of the process is only inferior to the process that the user is interacting with, and consistent with the priority of the visible process. Greatly reduces the chance of a process being killed.

When Android 2.3 starts calling setForeground Service to setForeground Service as foreground Service, a notice must be sent in the notification bar of the system. This means that foreground Service is bound to a visible notice. However, for applications that do not need to use the resident notification bar, this scheme is user-aware and cannot be used directly.

We can implement an internal Service, send a Notification with the same ID in both the LiveService and its internal Service, and then terminate the internal Service and the Notification. With the disappearance of the Notification, the user is no longer aware and the system priority is raised to 2.

2.2 Scope of Application: Version: Applicable to all Android versions.

2.3 Specific implementation: Refer to the open source project KeepProcessLive on Github.

4. Pull alive scheme after process is killed

1, use the system broadcast pull live

1.1 Scheme design: When a specific system event occurs, the system will send a response broadcast. If we “statically” register the corresponding broadcast listener in AndroidManifest, we can pull live when the response event occurs. Common broadcast events used to pull include:

1.2 Scope of application: Applicable to all Android platforms. However, it has the following disadvantages: 1. When the broadcast receiver is disabled by the management software or system software through the “auto start” function, it cannot receive the broadcast, and therefore cannot start itself. 2. System broadcast events are uncontrollable. The process can only be pulled alive when the broadcast event occurs, but cannot be pulled alive immediately after the process dies.

Therefore, the scheme was presented only as an alternative.

2. Use third-party applications to broadcast live

2.1 Scheme design: The design idea of the scheme is similar to that of receiving system broadcast, but the difference is that the scheme receives the broadcast of Top applications from the third party.

By decomcompiling third-party Top applications, such as mobile QQ, wechat, Alipay, UC browser, etc., as well as SDK such as Youmeng, Singe, Getui, etc., we find out their outgoing broadcasts and monitor them in the application. When these applications broadcast, our application will be activated.

2.2 Scope of application: The disadvantages of this scheme are the same as those of the system broadcast scheme mentioned above, as well as the following disadvantages: 1. The effect of process pulling depends on the number of third-party applications decomcompiled and analyzed. 2. Broadcasts of third-party applications are proprietary to the application, so broadcasts that are valid in the current version may be removed or changed to non-outgoing at any time in the subsequent version.

As a result, this option is only available as an alternative.

3. Use the system Service mechanism to pull

3.1 Scheme Design: In this scheme, the return value of the onStartCommand method of the Service is set to START_STICKY, so that the Service is automatically pulled off after the Service fails.

3.2 Application Scope: The Service cannot be pulled in the following two cases: 1. The Service restarts within 5 seconds after being killed for the first time, 10 seconds after being killed for the second time, and 20 seconds after being killed for the third time. However, if the Service is killed for five times within a short period of time, the system will not be pulled. 2. If a process is stopped by the management tool or system tool that has the Root permission through foreStop, the process cannot be restarted.

4. Use the JobScheduler mechanism to pull work

4.1 Scheme design: Android versions after 5.0 provide the JobScheduler interface, which is periodically called by the system to make the application perform some logical operations.

4.2 Application Scope: Mainly applicable to Android 5.0 or later. Forcestop does not affect forcestop in Android 5.0 or higher, and the application can still be pulled, which is very good. (On Xiaomi phones, however, it may occasionally fail to pull.)

4.3 Specific implementation: Refer to the open source project KeepProcessLive on Github.

5, use the account synchronization mechanism to pull live

5.1 Scheme Design: The Account synchronization mechanism of the Android system periodically synchronizes accounts. This scheme aims to use the synchronization mechanism to pull and live processes.

5.2 Application Scope: This function applies to all Android versions. Forestop processes can also be pulled alive. However, in the latest version of Android (Android N), the system seems to have changed account synchronization, so it will take some experimentation to see if this method can be used again.

5. Refer to the article

Android process to keep alive