第三方学习之鸿蒙&Android

Android保活方案

2021-06-01  本文已影响0人  海内灬存知己

1:low memory killer

系统出于性能和体验上的考虑,APP退到后台后并不会真正的kill、掉进程,而是将其缓存起来。
打开的应用越多,缓存的应用也就越多,在系统进程不足的情况下,系统根据自己的一套进程回收机制,来判断kill掉哪些进程,以腾出进程给需要的app,这套进程回收机制叫做low memory killer。

2:内存不足

内存阀值,每个手机都不一样,当可用内存小于该值得时候,Android就会杀死对应优先级得进程。

3:进程的优先级

进程的优先级通过oom_adj来判断,oom_adj取值如下:

adj级别 说明
UNKNOWN_ADJ 16 预留的最低级别,一般对于缓存的进程才有可能设置成这个级别
CACHED_APP_MAX_ADJ 15 缓存进程,空进程,在内存不足的情况下就会优先被kill
CACHED_APP_MIN_ADJ 9 缓存进程,也就是空进程
SERVICE_B_ADJ 8 不活跃的进程
PREVIOUS_APP_ADJ 7 切换进程
HOME_APP_ADJ 6 与Home交互的进程
SERVICE_ADJ 5 有Service的进程
HEAVY_WEIGHT_APP_ADJ 4 高权重进程
BACKUP_APP_ADJ 3 正在备份的进程
PERCEPTIBLE_APP_ADJ 2 可感知的进程,比如那种播放音乐
VISIBLE_APP_ADJ 1 可见进程
FOREGROUND_APP_ADJ 0 前台进程
PERSISTENT_SERVICE_ADJ -11 重要进程
PERSISTENT_PROC_ADJ -12 核心进程
SYSTEM_ADJ -16 系统进程
NATIVE_ADJ -17 系统起的Native进程

0-3是比较安全的oom_adj一般不会被系统杀死的,所以我们只要保证自己的app oom_adj在0-3之间就可以了。
可以通过adb命令:cat /proc /4181/oom_adj来查看自己app的oom_adj的值
4181是进程号

保活

方案1:activity1像素保活

原理:手机关闭屏幕的时候,偷偷创建一个activity,让应用成为前台进程,打开屏幕时关闭activity,这样用户就不会发现什么异常,我们知道前台应用的oom_adj为0是不会被杀死的,这样就达到看保活的目的。

        //设置1像素
        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);

缺点:activity不够干净,只有在息屏的时候才生效,存在局限性比较大,而且谷歌原生的系统息屏的时候不会清理进程,但是现在很多厂商会在息屏的时候清理内存,所以本方案的可行性不高,可以作为了解。

方案2:前台service保活

保活原理:启动一个前台服务,从而拉高整个应用的优先级。
因为一旦通知被用户干掉那么该保活方案就不好用了,所以通知图标存在与否是该方案是否可行的关键。
但是该方案是谷歌官方承认的保活方案,所以可行性还是很高的。
需要适配
API<18通知图标不会显示

//activity中
startservice(new Intent( packagecontext: this, Foregroundservice. class)):
//service中
startforeground(1, new Notification());

API>=18&&API<26可以启动双服务,绑定同样的D,然后stop
这个方法的原理是8.0系统之前会根据服务的id来判断通知,那么第二个id设置跟第一个相同,然后自杀,系统就会误认为此通知已死就不会通知了,那么通知栏上面就不会显示

//activity中
startservice(new Intent( packagecontext: this, Foregroundservice. class)):
//service中
startforeground(1, new Notification());
public static class Innerservice extends Service {
@Nullable
@Override
public Ibinder onbind(Intent intent){
return null;
}
@Override
public void oncreate() {
super.oncreate 
startforeground(1, new Notification())
stopself();
}

API>=26后暂时没有方式能够隐藏
8.0之后不可以创建同样的id的通知,所以此隐藏通知的方法就不好用了,当然了,通知显示与否不是该方案成功的评判标准,所以说还是可以用的。

拉活

1:广播拉活

1.1:系统广播拉活

在发生特定系统事件时,系统会发出广播,通过在 Androidmanifest中静
态注册对应的广播监听器,即可在发生响应事件时拉活
但是从 android7.0开始,对广播进行了限制,而且在8.0更加严格该方法就不适用了。

1.2:全家桶拉活

有多个app在用户设备上安装,只要开启其中一个就可以将其他的app也拉
活。比如手机里装了手Q、QQ空间、兴趣部落等等,那么打开任意一个app后,其
他的app也都会被唤醒

2:账户(account)同步拉活

系统每隔一段时间会进行账户同步,当系统去账户同步的时候(不一定多长时间,跟系统有关),我们就去拉活app,这个方案是非常稳定的,当然了国内的系统都是定制的,所以还是需要一定的适配的。
优点:系统唤醒,比较稳定
缺点:时间不能把控

2.1注册一个service,添加一个系统可识别的action

<service android: name- account. Authenticationservice
<intent-filter>
<action android: name-androld. accounts. Accountauthenticator
</intent-filter
<meta-data
android: name="android, accounts, Accountauthenticato
android: resource="@xml/account authenticator /
</service>

2.2service中通过binder把AccountAuthenticator 对象告诉系统

private AccountAuthenticator accountAuthenticator;
@override
public IBinder on Bind(Intent intent) {
return account Authenticator.getIBinder() ;
@override
public void onCreate() {
super.onCreate() ;
accountAuthenticator=new AccountAuthenticator(context:this) ;

2.3:同步账户:

public class Syncservice extends service{
private SyncAdapter mSyncAdapter;
private static final String TAG="SyncService";
@override
public IBinder onBind(Intent intent) {
return mSyncAdapter.getSyncAdapterBinder() ;
@override
public void onCreate() {
super.onCreate() ;
mSyncAdapter=new SyncAdapter(getApplicationContext() , true) ;
public static class SyncAdapter extends AbstractThreadedSyncAdapter{
public SyncAdapter(Context context, boolean auto Initialize) {
super(context, autoInitialize) ;
@override
public void onPerformSync(Accounta ccount, Bundle extras, String authority, ContentProvider clientprovider, SyncResult syncResult{
Log.e(TAG, “同步账户") ;
//与互联网或者本地数据库同步账户
}

2.4:添加权限

<uses-permission
android:name="android.permission.AUTHENTICATE_ACCOUNTS"
android:maxsdkversion="22"/>
<uses-permission
android:name="android.permission, GET_ACCOUNTS"
android:maxsdkversion="22"/>
<uses-permissionandroid:name="android.permission.MRITE_SYNC_SETTINGS"/>

3:JobScheduler拉活

JobScheduler允许在特定状态与特定时间间隔周期执行任务。可以利
用它的这个特点完成保活的功能,效果即开启一个定时器,与普通定时器不
同的是其调度由系统完成。
同样在某些ROM可能并不能达到需要的效果

@Requires Api(api=Build.VERSION.CODES.LOLLIPOP
public class MyJob service extends Jobservice{
public static void startJob(Context context) {
JobScheduler jobscheduler=(Jobscheduler) context.getSystemservice(Context.JOB_SCHEDULER_SERVICE) ;
JobInfo.Builder builder=new JobInfo.Builder(8, new ComponentName(context.get PackageName() ,
HyJob service.class.getName() ) ) .setPersisted(true) ;
//小于7.0
builder.setPeriodic(1000) ;//6.0以后最小是5s
//大于7.0
builder. set MinimumLatency(1000) ;//6.0以后最小是5s
job scheduler.schedule(builder.build() ) ;
}
@override
public boolean onStartJob(JobParameters params) {
//大于7.0
startJob(this);
return false;
}
@override
public boolean onStopJob(Jobparameters params) {
return false;
}
}
上一篇下一篇

猜你喜欢

热点阅读