Original author: “Sunshine dg in the Cracks”. This article was revised and published by Instant Messenger. Thanks for sharing it with me.
1, the preface
Android application survival final summary (A) : Android6.0 below the dual process daemon survival practice
Special note:
2. Series of articles
This is the second article in a series that Outlines the following:
- “Application survival (1) : dual-process daemon survival practices under Android6.0”
- “The final summary of application survival (ii) : Android6.0 and above survivability practices (process prevention)”
- Android6.0 and above survival practices (killed and resurrected)
3. Reference materials
How to keep the Android process alive: One article answers all your questions
Summary of Message push on Android: implementation principle, heartbeat survival, problems encountered, etc
Let’s take a closer look at the small matter of Android notifications
Why does TCP – based mobile IM still need the heartbeat keepalive mechanism?
Wechat team original sharing: Android version of wechat background to keep alive combat sharing (process to keep alive)
Wechat team original sharing: Android version of wechat background to live combat sharing (network to live)
Mobile IM practice: To realize the intelligent heartbeat mechanism of wechat on Android
Mobile IM practice: Analysis of heartbeat strategy of WhatsApp, Line and wechat
More of the same…
4, Andriod application survival core ideas
For Android6.0 and above system APP preservation, I think mainly through the following two aspects, namely:
- Lower the OMM_ADJ value so that the process is not killed by the system as much as possible (discussed in this article);
- Once a process is killed, it can be resurrected in other ways (discussed in the next article).
Next, we need to understand the rules that the Android system uses to reclaim processes in memory:
In order to understand the rules more intuitively, I drew a table:
Note: Priority 1 indicates the highest level. If oOM_ADJ of a common process is 0, and oOM_adj of a system process is less than 0, the system reclaims the process that meets the oOM_ADJ value based on the corresponding memory threshold. In addition, the oOM_adj value will increase with the use of physical memory, system processes will never be killed by the system.
5. Survival analysis of mainstream sports APPS in the market: Gudong (V 7.17.0)
5.1 One-click or sliding Cleaning
- A. When the “Goo dong” is stopped, its process is killed and the notification bar icon is cleared. It does not restart automatically after several minutes.
- B. When the “Ku Dong” is in motion state, the process dies and the notification bar icon is cleared. The process does not restart automatically after several minutes.
- C. When “Goo Dong” is in the suspended motion state, the process is alive and the notification bar icon is displayed normally. If it is cleaned separately, the process dies and the notification icon is cleared. However, when re-entering “Ku Dong”, it directly displays the movement interface instead of entering from the welcome interface, and the movement time and other states are the same as when it is cleared.
5.2 Black screen or Locked Screen
- A. When “Goo Dong” is stopped, go to the background and the lock screen goes to black. Wait for 5 minutes.
- B. When “Ku Dong” is in motion, step back to the background, lock the screen into black screen, and then enter the system, “Ku Dong” running interface automatically pops up. Lock the screen again and wait for 20 minutes. When the process is not killed, the “Goo Dong” running interface pops up automatically and the running status remains unchanged.
- C. When “Ku Dong” is suspended, step back to the background, the lock screen enters the black screen, and then enter the system, the “Ku Dong” running interface automatically pops up. Lock the screen again. Wait 20 minutes, the process is not killed, the “Goo Dong” running interface automatically pops up, the running status remains unchanged.
Premise:
- “Mobile Manager -> Lock Screen Cleaning app” closed
- “Mobile Phone Manager -> Self-start Management” closed
- In motion state, the back button is disabled, and the user can only go back to the background from the Home button.
- Motion interface text flashing or motion timing;
- Broken network.
Analysis:
- 1) When “Goo Dong” is stopped, one-button cleaning and black screen will be killed, indicating that the activation mechanism is not started before entering the motion interface (i.e. the motion interface is not switched to the background, etc.);
- 2) When the “Goo dong” is in motion, the one-key clean and black screen state are not killed (except for sliding clean), indicating that the active mechanism has been enabled: – ①” Goo Dong “disables the back button to ensure that the Activity is not destroyed; – ② Constantly update the timing of the notification bar to ensure that THE APP is always in the foreground and prevent it from being recycled by the system; – ③ The “goo dong” can restart automatically after being cleaned, and the notification will automatically pop up after being deleted, indicating that there may be another thing (Service or process) listener movement Service(or process) alive state, when the Service is destroyed, immediately pull it up; – (4) When “Goo Dong” is forcibly stopped or cleaned and killed, it will directly display the movement interface when it enters again and can maintain the movement state before killing, indicating that it may record the relevant state by using the configuration file; – ⑤ After the screen is locked or unlocked, the “Goo Dong” movement screen will pop up automatically, indicating that it uses the broadcast mechanism to monitor the screen lock broadcast, and the Activity will pop up to ensure that the process is always in the foreground.
Conclusion:
Remark:
6. Survival analysis of mainstream sports APPS in the market: Le Dynamics (V7.3.2)
6.1 One-click Or Sliding Cleaning
- Samsung C9(6.0) : In any state, “Le Dynamic” process is killed, wait a few minutes, no automatic start;
- 360F4(6.0) : In any state, “Le Dynamic” process is killed, wait a few minutes, no automatic start;
- Huawei Mate8(7.0) : In any state, “Le Dynamic” process is killed, wait a few minutes, and does not start automatically.
6.2 Locked screen/Black Screen
- A. When “Le Dynamic” is stopped, back to the background, lock the screen, wait for 5 minutes, the process dies, and the notification bar is cleared;
- B. When the “Le Dynamic” is in the motion pause state, back to the background, the lock screen is opened again, the motion interface is switched to the foreground, and the customized lock screen interface (overlying the system lock screen interface) is forced to play; Lock the screen again and wait 20 minutes. The application process is alive.
- C. When the “Le Dynamic” is in motion state, back to the background, the lock screen is opened again, the movement interface is switched to the foreground, and the customized lock screen interface is forced to play (overlying the system lock screen interface); Lock the screen again and wait 20 minutes. The application process is alive.
Premise:
- “Mobile Manager -> Lock Screen Cleaning app” closed
- “Mobile Phone Manager -> Self-start Management” closed
- In motion state, the back button is disabled, and the user can only go back to the background from the Home button.
- Broken network.
Analysis:
- When the “music power” is stopped and the screen is black, it is killed by the system in a short time, indicating that the keepalive mechanism is not enabled.
- But when in motion to suspend or to state, “le power” over a period of time has not been killed, and when the lock screen, “le power” will automatically movement interface to switch to the front desk, in addition, will also be forced to play from the lock screen interface, which means “music power” keep alive mechanism is likely to be used to monitor lock screen broadcast force the related interface to switch to the front desk, To improve the survival rate of The Joydrive in a black screen.
Conclusion:
7. Survival analysis of mainstream sports APPS in the market: Yue Moving Circle (V3.1.2.9)
7.1 One-click or sliding Cleaning
- Samsung C9(6.0) : the effect is consistent with Le Dynamics;
- 360F4(6.0) : The effect is consistent with music power;
- Huawei Mate8(7.0) : the effect is consistent with Le Dynamics.
6.2 Locked screen/Black Screen
- A. When the “Happy Moving circle” is stopped, back to the background, lock the screen, wait for 3 minutes, the process dies, and the notification bar is cleared;
- B. When the “Yue Moving circle” is suspended in motion, the customized lock screen and switch interface to the foreground are the same as those of Gudong and Le Power, with the same effect;
- C. When the “Yue Moving circle” is in motion, the customized lock screen and switch interface to the foreground are the same as the Goodong and Le Power, with the same effect.
Conclusion:
8. Principle of anti-kill scheme for APP process in this paper
9. APP process anti-killing scheme Step 1: Open the front Service and “force you to get on top”
DaemonService. Java:
/** foreground Service, use startForeground * this Service should be light as far as possible, do not occupy too much system resources, otherwise, * * Created by jianddongguo on 2017/7/7. */ public class DaemonService extends Service {private static final String TAG = "DaemonService"; public static final int NOTICE_ID = 100; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); If (contants.debug) log. d(TAG,"DaemonService---->onCreate called, start foreground service"); // If API is greater than 18, A visible Notification needs to pop up if(build.version.sdk_int >= build.version_codes.jelly_bean_mr2){notification.builder Builder = new Notification.Builder(this); builder.setSmallIcon(R.mipmap.ic_launcher); builder.setContentTitle("KeepAppAlive"); builder.setContentText("DaemonService is runing..." ); startForeground(NOTICE_ID,builder.build()); // Remove notifications by starting CancelNoticeService, Oom_adj values Intent Intent = new Intent (this, CancelNoticeService. Class); startService(intent); }else{ startForeground(NOTICE_ID,new Notification()); }} @override public int onStartCommand(Intent Intent, int flags, int startId) { Restart service return START_STICKY; } @Override public void onDestroy() { super.onDestroy(); // If the Service is killed, If (build.version.sdk_int >= build.version_codes.jelly_bean_mr2){NotificationManager mManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); mManager.cancel(NOTICE_ID); } if(contants.debug) log. d(TAG,"DaemonService---->onDestroy "); Intent Intent = new Intent(getApplicationContext(), daemonService.class); startService(intent); }}Copy the code
To illustrate, there are two other techniques used here:
- If a Service process is killed, the system tries to recreate the Service and preserves the start state of the Service but does not retain the Intent object. The onStartCommand method must be called again;
- The second is to restart itself in the onDestory method, that is, whenever the Service comes to the onDestory when it is destroyed, we restart it.
CancelNoticeService. Java:
/** Remove the Service notification bar flag, This Service selectively uses * * Created by Jianddongguo on 2017/7/7. */ public class CancelNoticeService extends Service {@nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if(Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2){ Notification.Builder builder = new Notification.Builder(this); builder.setSmallIcon(R.mipmap.ic_launcher); startForeground(DaemonService.NOTICE_ID,builder.build()); // Start a thread, New Thread(new Runnable() {@override public void run() {// delay 1s systemclocking. // Cancel foreground stopForeground(true) of CancelNoticeService; // Remove the notification displayed by DaemonService NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); manager.cancel(DaemonService.NOTICE_ID); // stopSelf(); } }).start(); } return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); }}Copy the code
Androidmanifest.xml:
<service android:name=".service.DaemonService"
android:enabled="true"
android:exported="true"
android:process=":daemon_service"/>
<service android:name=".service.CancelNoticeService"
android:enabled="true"
android:exported="true"
android:process=":service"/>Copy the code
Explain:
Test results:
E:\Android\StudioProject\KeepAppAlive>adb shell
shell@trltechn:/ $ su
root@trltechn:/ # ps | grep jiangdgCopy the code
root@trltechn:/ # cat /proc/15689/oom_adj
root@trltechn:/ # cat /proc/16033/oom_adjCopy the code
Note: If “/system/bin/sh: su: not found” is displayed after the su command is executed, the mobile device is not root. The ps command is used to display the static process status. The top command is used to monitor the process in real time. The KeepAppAlive process id is different each time you start it.
9, APP process anti-kill scheme second stage: monitor the lock screen broadcast, “create a ‘1 pixel’ tragedy”
ScreenManager. Java:
/** Created by Jianddongguo on 2017/7/8. */ public class ScreenManager {private static final String TAG = "ScreenManager"; private Context mContext; private static ScreenManager mSreenManager; Private WeakReference<Activity> mActivityRef; // use WeakReference to prevent memory leakage. private ScreenManager(Context mContext){ this.mContext = mContext; } public static ScreenManager getScreenManagerInstance(Context Context){if(mSreenManager == null){ mSreenManager = new ScreenManager(context); } return mSreenManager; } public void setSingleActivity(Activity mActivity){mActivityRef = new WeakReference<>(mActivity); } // Start SinglePixelActivity public void startActivity(){if(contants.debug) log.d (TAG," Ready to start SinglePixelActivity..." ); Intent intent = new Intent(mContext,SinglePixelActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(intent); } // End SinglePixelActivity Public void finishActivity(){if(contants.debug) log.d (TAG," Ready to end SinglePixelActivity..." ); if(mActivityRef ! = null){ Activity mActivity = mActivityRef.get(); if(mActivity ! = null){ mActivity.finish(); }}}}Copy the code
Explain:
A a = new A();
B b = new B(a);Copy the code
SinglePixelActivity. Java:
/**1 pixel Activity ** Created by Jianddongguo on 2017/7/8. private static final String TAG = "SinglePixelActivity"; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); If (contants.debug) log. d(TAG,"onCreate-- > start 1 pixel alive "); // Get the activity's Window object and set its property Window mWindow = getWindow(); mWindow.setGravity(Gravity.LEFT | Gravity.TOP); WindowManager.LayoutParams attrParams = mWindow.getAttributes(); attrParams.x = 0; attrParams.y = 0; attrParams.height = 1; attrParams.width = 1; mWindow.setAttributes(attrParams); / / to bind SinglePixelActivity ScreenManager ScreenManager. GetScreenManagerInstance (this). SetSingleActivity (this); } @override protected void onDestroy() {if(contants.debug) log.d (TAG,"onDestroy-- >1 pixel is destroyed "); if(! SystemUtils.isAppAlive(this,Contants.PACKAGE_NAME)){ Intent intentAlive = new Intent(this, SportsActivity.class); intentAlive.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intentAlive); Log. I (TAG,"SinglePixelActivity---->APP is dead, I need to restart it "); } super.onDestroy(); }}Copy the code
Explain:
SportsActivity. Java:
/** Start monitor lock screen broadcast, Create by Jianddongguo on 2017/7/7. */ public class SportsActivity extends AppCompatActivity {// Private ScreenReceiverUtil mScreenListener; // 1 pixel Activity management class private ScreenManager mScreenManager; // code omitted... private ScreenReceiverUtil.SreenStateListener mScreenListenerer = new ScreenReceiverUtil.SreenStateListener() { @ Override public void onSreenOn () {/ / removing "is 1 pixel" mScreenManager. FinishActivity (). } @override public void onSreenOff() { // IntEntIntent = new; // IntentIntent = new Intent(SportsActivity.this,SportsActivity.class); // startActivity(intent); / / if you feel that jump out SportActivity uncomfortable / / so we can make a "is 1 pixel" massacre mScreenManager. StartActivity (); Override public void onUserPresent() {Override public void onUserPresent() {Override public void onUserPresent(); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sports); if(Contants.DEBUG) Log.d(TAG,"--->onCreate"); MScreenListener = new ScreenReceiverUtil(this); mScreenManager = ScreenManager.getScreenManagerInstance(this); mScreenListener.setScreenReceiverListener(mScreenListenerer); } // code omitted... }Copy the code
Androidmanifest.xml:
<activity android:name=".SportsActivity" android:launchMode="singleTask"/> <activity android:name=".SinglePixelActivity" android:configChanges="keyboardHidden|orientation|screenSize|navigation|keyboard" android:excludeFromRecents="true" android:finishOnTaskLaunch="false" android:launchMode="singleInstance" android:theme="@style/SingleActivityStyle"/>Copy the code
Explain:
- The launchMode attribute is used to specify the launching mode of the activity. There are four types of launchMode: -standar mode. Each time an activity is started, an instance is created and added to the top of the task stack. – singleTop: every time you start an activity at the top of the stack, you do not need to create an instance of the activity. – singleTask mode: if an instance of an activity is started on the stack, it does not need to be created. You only need to add the activity to the top of the stack and pop all the activity instances above it. – singleInstance mode: The created activity instance is placed on a separate stack that stores only the instance as a shared instance.
- 2) Android :configChanges This is used to capture changes in the state of the phone, that is, to save the current state of the phone when it changes (e.g. switching between vertical and horizontal screens, screen size) and restart the Activity. Since SinglePixelActivity has a special mission to keep alive, we use the Android :configChanges property: To prevent the Activity from restarting, it simply calls onConfigurationChanged(Configuration newConfig) to notify the phone of the state change;
- 3) android: excludeFromRecents attributes: used to control the SinglePixelActivity not shown in the recent task list;
- 4) android: finishOnTaskLaunch attributes: used to tag when users back to start the application (TASK) whether to close the existing Activity instance, false said not to close;
- 5) Android: Theme property: used to specify the Activity to display the theme, here we define the theme SingleActivityStyle.
<style name="SingleActivityStyle" parent="horizontal_slide"> <! - form for transparent background color - > < item name = "android: windowBackground" > @ android: color/transparent < / item > <! <item name=" Android :windowFrame">@null</item> <! <item name=" Android :windowNoTitle">true</item> <! <item name=" Android :windowIsFloating">true</item> <! - custom TitleBar when remove the shadow - > < item name = "android: windowContentOverlay" > @ null < item > <! - do not allow the form background dark - > < item name = "android: backgroundDimEnabled" > false < / item > <! - switch form without animation -- -- > < item name = "android: windowAnimationStyle" > @ null < / item > <! - disable preview window animation - > < item name = "android: windowDisablePreview" > true < / item > < item name = "android: windowNoDisplay" > false < / item > </style>Copy the code
Test results:
9, APP process anti-kill scheme third stage: play a silent audio loop, “build king Kong not bad body”
Look at goo-dong this silent music playback way to keep alive, enough shameless bar:
PlayerMusicService. Java:
/** Play a silent audio loop, * * Created by Jianddongguo on 2017/7/11. */ Public Class PlayerMusicService extends Service {private final * * Created by JiandDongguo on 2017/7/11 static String TAG = "PlayerMusicService"; private MediaPlayer mMediaPlayer; @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); If (Contants. DEBUG) Log. D (the TAG, the TAG + "-- -- -- - > onCreate, start the service"); mMediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.silent); mMediaPlayer.setLooping(true); } @Override public int onStartCommand(Intent intent, int flags, int startId) { new Thread(new Runnable() { @Override public void run() { startPlayMusic(); } }).start(); return START_STICKY; } private void startPlayMusic(){ if(mMediaPlayer ! = null){if(contants.debug) log. d(TAG," start background music "); mMediaPlayer.start(); } } private void stopPlayMusic(){ if(mMediaPlayer ! = null){if(contants.debug) log. d(TAG," disable background music "); mMediaPlayer.stop(); } } @Override public void onDestroy() { super.onDestroy(); stopPlayMusic(); If (Contants. DEBUG) Log. D (the TAG, the TAG + "-- -- -- - > onCreate, stop services"); / / restart Intent Intent = new Intent (getApplicationContext (), PlayerMusicService. Class); startService(intent); }}Copy the code
Androidmanifest.xml:
<service android:name=".service.PlayerMusicService"
android:enabled="true"
android:exported="true"
android:process=":music_service"/>Copy the code
Test results:
- 1) Huawei Mate8(Android 7.0) : Put the test APP in the background, the front Service will be killed within 1 minute under the black screen, and the “1-pixel” suspended Activity will survive the test under the black screen for 2 hours, and the effect is ok. However, when the user clicks to clean up the latest app, it will be killed. When the Serive loop plays a silent audio in the background, the one-click clean up will still survive, and it will survive in the black screen mode in the background for more than 12 hours.
- 2) Samsung C9(Android 6.0) : Open foreground Service and 1 pixel, KeepAppAlive can survive in black screen background mode for more than 9 hours, it seems that the native system is still more gentle; The background audio playback service is enabled, and the user can delete the recent application successfully with one click.
- 3) Huawei 4X(Android 6.0) : same effect as C9;
- 4) Samsung Note4(Android 5.0) : same effect as C9.
Note: Mate8 plays a loop of silent audio, KeepAppAlive will not be killed when the user clicks one button to clean up the latest app, but will also be killed if the user only chooses to clean KeepAppAlive, which is the same as the “Goo Dong” keepalive effect.
Samsung C9(Android 6.0)
Huawei Mate8(Android 7.0) :
Download the source code
KeepingAppAlive-master(52im.net).zip
(1.29 MB, download times: 0, price: 3 gold)
11, the next trailer
Click here to enter