1.1: 前台service
只需要搞定在状态栏的notification就可以了,同时启动两个id相同的前台Service,然后再将后启动的Service做stop处理,主要是利用了系统的一个漏洞,但是在7.0系统,Android将漏洞封堵了,该方法不管用了,还在探索7.0的具体方法。下边是前台service的具体使用方法。
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
startForeground(NOTIFICATION_ID, new Notification());
} else {
//启动守护Service
try {
Intent innerIntent = new Intent(this, KernelService.class);
startService(innerIntent);
startForeground(NOTIFICATION_ID, new Notification());
} catch (Exception e) {
TraceLogger.e("Start kernel service err", e);
}
}
public static class KernelService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
try {
// 两个service使用同一个notification ID
startForeground(NOTIFICATION_ID, new Notification());
stopForeground(true);
stopSelf();
} catch (Exception e) {
TraceLogger.e("Set foreground & stop kernel service", e);
}
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
1.2: 账号同步机制
该功能本来是设计用来进行账号同步,但是可以利用这个机制来保活
private void createSyncAccount(Context context) {
Account newAccount = new Account(Consts.ACCOUNT_NAME, Consts.ACCOUNT_TYPE);
AccountManager accountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
/*
* Add the account and account type, no password or user data
* If successful, return the Account object, otherwise report an error.
*/
try {
if (accountManager.addAccountExplicitly(newAccount, null, null)) {
/*
* If you don't set android:syncable="true" in
* in your element in the manifest,
* then call context.setIsSyncable(account, AUTHORITY, 1)
* here.
*/
ContentResolver.setIsSyncable(newAccount, Consts.AUTHORITY, 1);
ContentResolver.setSyncAutomatically(newAccount, Consts.AUTHORITY, true);
Random random = new Random();
int interval = 1800 + random.nextInt(600);
ContentResolver.addPeriodicSync(newAccount, Consts.AUTHORITY, Bundle.EMPTY, interval);
} else {
/*
* The account exists or some other error occurred. Log this, report it,
* or handle it internally.
*/
}
} catch (Exception e) {
Log.w("SplashActivity", "createSyncAccount err", e);
}
}
1.3: 智能心跳
心跳根据网络情况,运营商策略的不同而不同,在GOOGLE IO我曾尝试去问GOOGLE的工程师Android 系统的心跳策略是如何来做的,但是被拒绝了,因为这涉及到不同国家运营商的策略。
最小心跳间隔状态的最佳状态逻辑:以最小间隔启动增长查询,成功则以固定步长增长,增长到最大心跳间隔,停止增长。当连续多次出现下一个心跳间隔心跳失败时。则上一次成功间隔为最佳心跳,并放入缓存。心跳不能小于最小心跳。最佳心跳状态逻辑:由于最佳心跳为上次查找的最佳值,理想状态即使用最佳状态。但当最佳状态出现连续多次失败时,则恢复到最小心跳状态,并开始重新查找。
1.4: ACCS接入
我们都知道,如果一个进程占用的内存很大,那么会增大被系统杀掉的几率,使用一个较小的进程来与服务器端进行交互就显得非常重要了,非常幸运的是,集团里有ACCS,手淘和一些其它的业务都有接入ACCS,这里就不需要钉钉再去重复搞这么一套机制,同时还有一个好处,手淘的安装量大,同时手淘和很多的手机厂商都有合作,有白名单,只要手淘活着,那么我们这些APP就能被手淘拉起来,何乐而不为呢,况且ACCS的接入还是很简单的。