文章

进程保活、拉活

进程保活、拉活

进程保活拉活

进程管理

  • LowMemoryKiller

ADJ算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
1.ps | grep 包名  //查看当前app的进程号

2.cat /proc/进程号/oom_adj  //查看当前进程的adj值(早期android和linux使用,现已废弃,但仍然有效)

3.cat /proc/进程号/oom_score_adj    //这个是新版本的查看adj的命令,adj有效值为-1000~1000
    
  ADJ级别                 取值     含义

NATIVE_ADJ              -1000   native进程
SYSTEM_ADJ              -900    仅指system_server进程
PERSISTENT_PROC_ADJ     -800    系统persistent进程
PERSISTENT_SERVICE_ADJ  -700    关联着系统或persistent进程
FOREGROUND_APP_ADJ      0       前台进程
VISIBLE_APP_ADJ         100     可见进程
PERCEPTIBLE_APP_ADJ     200     可感知进程比如后台音乐播放
BACKUP_APP_ADJ          300     备份进程
HEAVY_WEIGHT_APP_ADJ    400     重量级进程
SERVICE_ADJ             500     服务进程(A list中的service)
HOME_APP_ADJ            600     Home进程
PREVIOUS_APP_ADJ        700     上一个进程
SERVICE_B_ADJ           800     B List中的Service
CACHED_APP_MIN_ADJ      900     不可见进程的adj最小值
CACHED_APP_MAX_ADJ      906     不可见进程的adj最大值
    

// 当系统剩余空闲内存低于某阈值(比如147MB),则从ADJ大于或等于相应阈值(比如900)的进程中,选择ADJ值最大的进程
// 如果存在多个ADJ相同的进程,则选择内存最大的进程
----------ADJ----------------Memory Left------------
FOREGROUND_APP_ADJ(0)          73MB
VISIBLE_APP_ADJ(100)           92MB
PERCEPTIBLE_APP_ADJ(200)       110MB
BACKUP_APP_ADJ(300)            129MB
CACHED_APP_MIN_ADJ(900)        221MB
CACHED_APP_MAX_ADJ(906)        332MB

进程保活

1像素保活

  • 关闭屏幕时创建Activity,使其成为前台进程;打开屏幕时,关闭Activity
  • 缺点是锁屏后才能提权
  • 注册清单里注册activity
1
2
3
4
5
<!--要开启新的任务栈,并且在最近清单里隐藏-->
<activity android:name=".KeepActivity"
    android:excludeFromRecents="true"
    android:taskAffinity="com.example.mykeepalive"
    android:theme="@style/KeepLiveTheme"/>
  • theme中添加透明
1
2
3
4
<style name="KeepLiveTheme" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    <item name="android:windowBackground">@null</item>
    <item name="android:windowIsTranslucent">true</item>
</style>
  • KeepActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.example.mykeepalive;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.Nullable;

public class KeepActivity extends Activity {

    private static final String TAG = "KeepActivity";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Log.d(TAG, "启动keep");

        Window window = getWindow();
        window.setGravity(Gravity.START | Gravity.TOP); // 放在左上角

        WindowManager.LayoutParams params = window.getAttributes();
        // 宽高
        params.width = 1;
        params.height = 1;
        // 起始坐标
        params.x = 0;
        params.y = 0;
        window.setAttributes(params);

        // 创建一个弱引用
        KeepManager.getInstance().setKeepActivity(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "关闭keep");
    }
}
  • KeepManager.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.example.mykeepalive;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;

import java.lang.ref.WeakReference;

public class KeepManager {
    private static final KeepManager INSTANCE = new KeepManager();
    private KeepReceiver keepReceiver;
    private WeakReference<Activity> keepActivity; // 弱引用,防止内存泄漏(JVM垃圾回收时,无论内存是否充足都会回收被弱引用关联的对象)

    private KeepManager(){
    }

    public synchronized static KeepManager getInstance(){
        return INSTANCE;
    }

    public void setKeepActivity(KeepActivity keepActivity) {
        this.keepActivity = new WeakReference<>(keepActivity);
    }

    // 开启透明Activity
    public void startKeepActivity(Context context){
        Intent intent = new Intent(context, KeepActivity.class);
        // 创建一个新的task,退出1像素activity时,返回launch。若用原来的task,开屏后关掉1像素activity返回的是当前task栈里的mainactivity
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    // 关闭透明Activity
    public void finishKeepActivity(){
        if (keepActivity != null && keepActivity.get() != null){
            keepActivity.get().finish();
        }
    }

    // 注册开屏关屏广播
    public void registerKeepReceiver(Context context){
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_SCREEN_ON);
        filter.addAction(Intent.ACTION_SCREEN_OFF);

        keepReceiver = new KeepReceiver();
        context.registerReceiver(keepReceiver, filter);
    }

    // 反注册
    public void unregisterKeepReceiver(Context context){
        if (keepReceiver != null){
            context.unregisterReceiver(keepReceiver);
        }
    }
}
  • KeepReceiver.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.example.mykeepalive;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;

public class KeepReceiver extends BroadcastReceiver {
    private static final String TAG = "KeepReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();

        Log.d(TAG, "onReceive: " + action);

        if (TextUtils.equals(action, Intent.ACTION_SCREEN_OFF)){
            // 关闭屏幕时,开启1像素activity
            KeepManager.getInstance().startKeepActivity(context);

        }else if (TextUtils.equals(action, Intent.ACTION_SCREEN_ON)){
            // 打开屏幕时,关闭
            KeepManager.getInstance().finishKeepActivity();
        }
    }
}
  • MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.example.mykeepalive;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //1像素且透明Activity提升App进程优先级
        KeepManager.getInstance().registerKeepReceiver(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //反注册防止内存泄漏
//        KeepManager.getInstance().unregisterKeepReceiver(this);
        Log.d("xxx", "onDestroy: ");
    }

}

前台服务保活

本文由作者按照 CC BY 4.0 进行授权