进程保活、拉活
进程保活、拉活
进程保活拉活
进程管理
- 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 进行授权