当手机在内存不足的时候,系统会GC,杀一些进程之类的来减低内存的使用,如果我们的程序还想在后台的激烈内存争夺战中活下去,必须要有一些异于常人的必杀技,为此罗列以下几个常见的绝招,绝招能力逐次递增。
绝招一,凤凰盘涅法
public class ThisService extends Service {
public void onDestroy() {
super.onDestroy();
startService(new Intent(this, ThisService.class));
}
}
在这个大法中,我们让他在被关闭的同时启动自己,置之死地而后生。
但这方法并不是无敌的,并不确保程序被关还能重启。
另外一种盘涅方法是
onStartCommand方法,返回START_STICKY
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
flags = START_STICKY;
return super.onStartCommand(intent, flags, startId);
}
手动返回START_STICKY,当service因内存不足被kill,当内存又有的时候,service又被重新创建,比较不错,但是不能保证任何情况下都被重建,比如进程被干掉了….
StartCommond几个常量参数简介:
- START_STICKY
在运行onStartCommand后service进程被kill后,那将保留在开始状态,但是不保留那些传入的intent。不久后service就会再次尝试重新创建,因为保留在开始状态,在创建 service后将保证调用onstartCommand。如果没有传递任何开始命令给service,那将获取到null的intent。 - START_NOT_STICKY
在运行onStartCommand后service进程被kill后,并且没有新的intent传递给它。Service将移出开始状态,并且直到新的明显的方法(startService)调用才重新创建。因为如果没有传递任何未决定的intent那么service是不会启动,也就是期间onstartCommand不会接收到任何null的intent。 - START_REDELIVER_INTENT
在运行onStartCommand后service进程被kill后,系统将会再次启动service,并传入最后一个intent给onstartCommand。直到调用stopSelf(int)才停止传递intent。如果在被kill后还有未处理好的intent,那被kill后服务还是会自动启动。因此onstartCommand不会接收到任何null的intent。
绝招二,排头兵大法
我们知道程序处于可见的状态的程序优先级是最高的,不可见一般都相对低,所以我们需要成为可见的排头兵!!
public class ThisService extends Service {
private int NOTIFI_ID=2390;
public void onCreate() {
super.onCreate();
showNotif();
}
public void showNotif() {
Intent trackIntent = new Intent(this, TrackActivity.class);
PendingIntent pendingTrackActivity = PendingIntent.getActivity(this, 0, trackIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setPriority(Notification.PRIORITY_MAX)
.setOngoing(true)
.setContentTitle("slogan")
.setContentText("ContentText")
.setSmallIcon(R.drawable.icon_app)
.setContentIntent(pendingTrackActivity).build();
startForeground(NOTIFI_ID, notification);
}
}
这里重要的一句就是startForeground(NOTIFI_ID, notification);
,它把我们默认在后台运行的程序变成了在前台运行显示的,例如我们的音乐,在通知栏有一个播放状态的通知。一般音乐类靠这招就可以活下去,不被系统回收。
对于绑定了这个service的activity,他的优先级也是提高的,不会被优先回收掉,就像我们的音乐播放器一样!但这个设置为前端可见的通知栏没办法消失,这个就是谷歌一开始为了避免滥用而设计的。对于不想有通知栏显示的发难。就只能看下面的绝招了。
绝招三,持久
<application
android:name="com.test.Application"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:persistent="true"
android:theme="@style/AppTheme" >
</application>
在我们的application属性中,设置android:persistent="true"
为真,他可以提高我们程序的优先级,这个优先级介于系统程序和一般程序之间。跟详细的介绍可以看这篇文章 说说Android应用的persistent属性
绝招四,优先级
<service
android:name="com.dbjtech.acbxt.waiqin.UploadService"
android:enabled="true" >
<intent-filter android:priority="1000" >
<action android:name="com.dbjtech.myservice" />
</intent-filter>
</service>
在AndroidManifest.xml
文件中对于intent-filter可以通过android:priority = "1000"
,这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时适用于广播。
绝招五,双子星
打开我们的设置,查看正在运行的程序,发现有不少的程序有两个经常,两个服务,例如某信,他们就是这样的方案,最近还爆出了某FM居然开五个后台进程和服务,宙斯,普罗米修斯代码来刷活跃度数据!至于是真是假,我也不知道,不想去深究,没必要折腾,砸门知道这招可以救活我们的程序就好啦。
这个方案其实就是典型的守护进程,查阅下AIDL深入了解下,下次有空再继续写。
最后绝招,无敌。
有一种东西,出在后台缺永远不会死去,简直无敌,你知道是什么吗?
电话,短信等!!
他们怎么做到的?他们是系统级应用啊!
把自己的app弄到/SYS/app里面去。