经过整理可行的方案有以下四种,最好配合使用:
1.前台服务
前台服务是被认为是用户已知的正在运行的服务,当系统需要释放内存时不会优先杀掉该进程,前台服务必须有一个 notification 在状态栏中显示。
NotificationCompat.Builder nb = new NotificationCompat.Builder(this);
nb.setOngoing(true);
nb.setContentTitle(getString(R.string.app_name));
nb.setContentText(getString(R.string.app_name));
nb.setSmallIcon(R.drawable.icon);
PendingIntent pendingintent =PendingIntent.getActivity(this, 0, new Intent(this, Main.class), 0);
nb.setContentIntent(pendingIntent);
startForeground(1423, nb.build());
【可行性】此方法对防止系统回收有一定的效果,可以减少被回收的概率,但是系统在内存极低的情况下,该Service还是会被kill掉,并且不一定会重启。而清理工具或者手动强制结束,进程直接挂掉,并不会重启。
2.监听系统广播
通过监听系统的一些广播,比如:手机开机、解锁屏、网络连接状态变更、应用状态改变等等,然后判断Service是否存活,若否则启动Service。
【可行性】Android系统在3.1版本以后为了加强系统安全性和优化性能对系统广播进行了限制,应用监控手机开机、解锁屏、网络连接状态改变等有规律的系统广播在android3.1以后,首次安装未启动或者用户强制停止后,应用无法监听到。Android N取消了网络切换广播。
3.应用之间互拉
利用不同的app进程使用广播来进行相互唤醒,比如支付宝、淘宝、天猫、等阿里系的app,如果打开其中任意一个应用,其它阿里系的app也会唤醒了,其实BAT系都差不多。另外现在很多推送sdk也会唤醒app。
【可行性】多个app应用唤醒需要相互之间有关联才能实现,推送sdk应用间唤醒当用户强制停止后无法唤醒。
4.利用Android系统提供的帐号和同步机制实现
在应用中建立一个帐号,然后开启自动同步并设置同步间隔时间,利用同步唤醒app。账号建立后在手机设置-账号中能看到应用的账号,用户可能会删除账号或者停止同步,故需要经常检测账号是否能正常同步。
//建立账号
AccountManager accountManager = AccountManager.get(mContext);
Account riderAccount = new Account(mContext.getString(R.string.app_name), Constant.ACCOUNT_TYPE);
accountManager.addAccountExplicitly(riderAccount, mContext.getString(R.string.app_name), null);
ContentResolver.setIsSyncable(riderAccount, Constant.ACCOUNT_AUTHORITY, 1);
ContentResolver.addPeriodicSync(riderAccount, Constant.ACCOUNT_AUTHORITY, new Bundle(), 60);
//开启同步
ContentResolver.setSyncAutomatically(riderAccount, Constant.ACCOUNT_AUTHORITY, true);