Android process live

The way to keep the process alive

Some mechanisms of Android killing process

Androcchio's processes are mainly divided into the following five categories:
1. Foreground process
Foreground Process
2. Visible process
Visible Process
3. Service process
Service Process
4. Background process
Background Process
5. Empty process
Empty Process

Android's mechanism is to kill the corresponding hierarchical process when the memory reaches a certain threshold. The method to view the threshold value is shown in the following figure (unit: 4KB). Of course, there will be differences in different customized systems, and the handset manufacturer will modify the value. Except for the fifth one from the left, all the others correspond to the above five levels one by one. If the memory is less than 80640 * 4KB / 1024 = 315MB, the empty process will be killed

Some ways to keep alive

One pixel survival method

The principle is to monitor the status of the screen. When the screen is locked, start a one pixel Activity so that the process will become a foreground process, which will not be killed when the screen is locked. The Activity is closed when the screen is on.

1. First, you need to register a broadcast monitor in MainActivity to monitor the screen status of the mobile phone:

//Register broadcast on monitor screen
mOnepxReceiver = new OnePixelReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.SCREEN_OFF");
intentFilter.addAction("android.intent.action.SCREEN_ON");
intentFilter.addAction("android.intent.action.USER_PRESENT");
registerReceiver(mOnepxReceiver, intentFilter);

2. Processing after monitoring the screen status:

public class OnePixelReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {    //Screen off start 1 pixel Activity
        Intent it = new Intent(context, OnePiexlActivity.class);
        it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(it);
    } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {   //Screen open end 1 pixel
        context.sendBroadcast(new Intent("finish"));
        Intent main = new Intent(Intent.ACTION_MAIN);
        main.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        main.addCategory(Intent.CATEGORY_HOME);
        context.startActivity(main);
    }
}
}

Start mode is FLAG_ACTIVITY_NEW_TASK, otherwise the most advanced task can see that the whole process is covered by an activity.
3. Create one pixel activity

public class OnePiexlActivity extends Activity {

private BroadcastReceiver endReceiver;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //Set 1 pixel
    Window window = getWindow();
    window.setGravity(Gravity.LEFT | Gravity.TOP);
    WindowManager.LayoutParams params = window.getAttributes();
    params.x = 0;
    params.y = 0;
    params.height = 1;
    params.width = 1;
    window.setAttributes(params);

    //End broadcast of this page
    endReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            finish();
        }
    };
    registerReceiver(endReceiver, new IntentFilter("finish"));
    //Check screen status
    checkScreen();
}

@Override
protected void onResume() {
    super.onResume();
    checkScreen();
}

/**
 * Check the screen status isScreenOn is true. The screen "lights up" to end the Activity 
 */
private void checkScreen() {

    PowerManager pm = (PowerManager) OnePiexlActivity.this.getSystemService(Context.POWER_SERVICE);
    boolean isScreenOn = pm.isScreenOn();
    if (isScreenOn) {
        finish();
    }
}
}

At the same time, set the activity to transparent, or it may be seen by users.

<style name="OnePixelActivity" parent="android:Theme.Holo.Light.NoActionBar">//Untitled
    <item name="android:windowIsTranslucent">true</item>//transparent
</style>
<activity
    android:name=".OnePiexlActivity"
    android:screenOrientation="portrait"
    android:excludeFromRecents="true"
    android:theme="@style/OnePixelActivity"/>

android:excludeFromRecents= "true" sets that the activity stack does not appear in the recent tasks list.

I heard that this method is no longer available. I don't know why. Maybe it has been optimized by Google on the new system.
Disadvantages: you must turn off the screen to keep it alive. If the user continues to use the phone for several hours. The process may have been killed in the background.

Front desk service

The principle is to start a front desk service. However, starting the foreground service will display a notice that cannot be eliminated in the notice bar.
The method to start the foreground service is very simple, as long as startforegroup (int, notification) is called in the onCreate method of the service.

Different versions of api notification bar display different:

The API < 18 notification icon will not be displayed.
API > = 18 & & API < 26 can start two services, bind the same ID, and then stop one service, the notification icon will not be displayed naturally.
There is no way to hide notifications after API > = 26

public class MyService extends Service {
    public static final int NOTIFICATION_ID=0x11;

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        
        if (Build.VERSION.SDK_INT <Build.VERSION_CODES.JELLY_BEAN_MR2) {
            startForeground(NOTIFICATION_ID, new Notification());
        } else {
            
            Notification.Builder builder = new Notification.Builder(this);
            builder.setSmallIcon(R.mipmap.ic_launcher);
            startForeground(NOTIFICATION_ID, builder.build());
            startService(new Intent(this, InnerService.class));
        }
    }

    public  static class  InnerService extends Service{
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
        @Override
        public void onCreate() {
            super.onCreate();
            //Send a Notification with the same ID as the above service, then cancel it and cancel its foreground display
            Notification.Builder builder = new Notification.Builder(this);
            builder.setSmallIcon(R.mipmap.ic_launcher);
            startForeground(NOTIFICATION_ID, builder.build());
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    stopForeground(true);
                    NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                    manager.cancel(NOTIFICATION_ID);
                    stopSelf();
                }
            },100);

        }
    }
}

Tags: Android less Mobile Google

Posted on Wed, 10 Jun 2020 00:58:40 -0400 by juline