• QQ
  • nahooten@sina.com
  • 常州市九洲新世界花苑15-2

Android

Android几种Service常驻内存的小思绪

原创内容,转载请注明原文网址:http://homeqin.cn/a/wenzhangboke/jishutiandi/Android/2019/0612/537.html

 

老话说的好:躲得了月朔,躲只是高三 ! 大无数的Android开发人员遇到的一个题目—怎样包管Service常驻内存。 近期我最终也在名目中务必走运的遇到了

 

先来打听一下甚么是Service常驻内存。

所谓Service常驻内存,意思即是想让本人写的Service服无在手机开机以后就永远处于执行状况。

 

举个Example先, 好比朋友们最熟悉的微信和QQ,每当手机开机以后,微信和QQ都是本人主动就在后台执行,及时的汲取谈天信息,并且QQ和微信差点儿是永远处于执行状况(即便是用户通过种种暴力体例将Service服无关掉页也没用)

 

再看一下Service可能被关掉的几种体例

第一种 Android体系有一个内存护卫机制。当体系可用内存不及时。为了包管目前正在执行的历程(大概说Activity)能够平常执行。体系会主动的将少许优先级比較低的历程给杀掉,固然在此历程中的Service也会跟着一路被杀死。

对于历程的优先级是怎么排的 能够參考一下几个优先级排序的规则 : 

在Android中一共同拥有5种历程的分类,遵照优先级从高到低的挨次各自是:

 

前台历程

 

a . 历程中包孕处于前台的正与用户交互的activity;

b. 历程中包孕与前台activity绑定的service;

c. 历程中包孕挪用了startForeground()要领的service;

d. 历程中包孕正在执行onCreate(), onStart(), 或onDestroy()要领的service;

e. 历程中包孕正在执行onReceive()要领的BroadcastReceiver.

f. 体系中前台历程的数目最少, 前台历程差点儿不会被杀死. 仅仅有当内存低到无法包管扫数的前台历程统一时候执行时才会选定杀死某个前台历程.

可视历程

 

a. 历程中包孕未处于前台但仍旧可见的activity(挪用了activity的onPause()要领, 但没有挪用onStop()要领). 典范的环境是执行activity时弹出对话框, 此时的activity只管不是前台activity, 但其仍旧可见.

b. 历程中包孕与可见activity绑定的service.

c. 可视历程不会被体系杀死, 除非为了包管前台历程的执行而不得已为之

服无历程

 

历程中包孕已启动的service.

后台历程

 

a. 历程中包孕不行见的activity(onStop()要领挪用后的activity).

b. 后台历程不会干脆影响用户体验, 为了包管前台历程/可视历程/服无历程的执行, 体系随时都有可能杀死一个后台历程.

c. 一个精确的实现了性命周期要领的activity处于后台时被体系杀死, 能够在用户又一次启动它时恢复以前的执行状况.

空历程

 

不包孕岂论甚么处于活动状况的历程是一个空历程. 体系每每杀死空历程, 这不会造成岂论甚么影响. 空历程存在的唯一理由是为了缓存少许启动数据, 以便下次能够更快的启动.

另外一种 用户能够在App经管界面主动的将Service服无强迫关闭,如图所看到的:

这里写图片刻画论述

 

第三种 即是现在市面上多见的少许Clear Master之类的App清理器。好比MIUI自带的清空RAM、手机管家、360等等。

通过这些类似的三方APP。也可以将正在执行中的历程给强迫关闭

 

最后再来看一下我们这篇文章的主题:怎样建立一个在以上三种清空下都不会被强迫关闭的Service(听起来有点吊炸天的赶脚)

起首我们必要打听一点,以上三种体例究竟上在最终framework层都是挪用PM的killProcess要领将某历程给干脆杀死。但是我们在做表层App开发时(源代码下的二次开发另当别论),又无法窜改framework层的关联代码,所以我们不行能从基础上避让历程被杀死这一举动。

 

是以我的思绪即是假定提供某一种机制。如许的机制能够在划定时间内。频繁的去启动某Service, 而假定我们去启动一个曾经被建立的Service时,它的onCreate要领是不会再被挪用的。

 

详细实现体例有比方以下几种: 

1 窜改Service的onStartCo妹妹and要领中的回笼值。onStartCo妹妹and要领有三种回笼值,顺次是 

START_NOT_STICK:

 

当Service被最杀死时。体系不会再去测试再次启动这个Service

START_STICKY

 

当Service被最杀死时。体系会再去测试再次启动这个Service,但是以前的Intent会丧失,也即是在onStartCo妹妹and中汲取到的Intent会是null

START_REDELIVER_INTENT

 

当Service被最杀死时,体系会再去测试再次启动这个Service。并且以前的Intent也会又一次被传给onStartCo妹妹and要领

通过窜改onStartCo妹妹and要领的回笼值这一要领足以办理上头我们提到Service被关闭的第一种环境。 但是对于用户主动强迫关闭和三方经管器照旧没有用果的

 

2 通过监听某些体系每每发出的播送,当汲取到播送以后我们能够主动的去测试启动Service,假定此Service曾经被建立,则不会再走onCreate要领。否则这个Service就会被再次启动. 

举几个每每应用的体系播送的样例:

 

Intent.ACTION_BATTERY_CH 电池电量产生改变

Intent.ACTION_AIRPLANE_MODE_CHANGED; 翻开或关闭遨游形式

Intent.PHONE_STATE_CHANGED_ACTION 电话状况产生改变

如许的要领能够办理Service被关闭的扫数景象。 但是缺点是不短长常稳定,毕竟要汲取到某些体系播送以后才干执行启动Service的操纵,是以有必然的延时,乃至没有胜利的再次启动Service (对于有望Service被再次启动的渴慕最强烈的童鞋,不建议应用如许的要领)

 

3 通过挪用AlarmManager的setRepeating要领,我们能够每隔一段时间就去启动Service一次,代码比方以下所看到的:

 

Calendar cal = Calendar.getInstance();

        Intent intent = new Intent(this, MyService.class);

        PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);

 

        AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);

 

        // 每分钟启动一次。这个时间值视详细环境而定

        alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 60*1000, pintent);

如许的体例也可以办理Service被关闭的扫数景象。并且能够在一分钟内接续的去测试启动Service。这个时间值是能够本人调的。

 

上篇:上一篇:AccessibilityService的应用
下篇:下一篇:办理安卓打包apk安置后翻开闪退的问题