1.关于进程守护无非就是6.0以下,6.0以上的高版本保活
a.android中6.0以下的保护采用双线程守护即可是aidl
(1)创建aidl文件
interface IServiceAidlInterface {
String getServiceName();
}
(2)创建本地service是LocalService类实现aidl接口
public class LocalService extends Service {
MyBinder binder;
MyConn conn;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
@Override
public void onCreate() {
super.onCreate();
binder = new MyBinder();
conn = new MyConn();
}
class MyBinder extends IServiceAidlInterface.Stub {
@Override
public String getServiceName() throws RemoteException {
return LocalService.class.getSimpleName();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(LocalService.this, " 本地服务活了", Toast.LENGTH_SHORT).show();
this.startService(new Intent(LocalService.this,RomoteService.class));
this.bindService(new Intent(LocalService.this,RomoteService.class),conn, Context.BIND_IMPORTANT);
return START_STICKY;
}
class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("box", "绑定上了远程服务");
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("box", "远程服务被干掉了");
Toast.makeText(LocalService.this, "远程服务挂了", Toast.LENGTH_SHORT).show();
//开启远程服务
LocalService.this.startService(new Intent(LocalService.this,RomoteService.class));
//绑定远程服务
LocalService.this.bindService(new Intent(LocalService.this,RomoteService.class),conn,Context.BIND_IMPORTANT);
}
}
@Override
public void onDestroy() {
super.onDestroy();
//开启远程服务
LocalService.this.startService(new Intent(LocalService.this,RomoteService.class));
//绑定远程服务
LocalService.this.bindService(new Intent(LocalService.this,RomoteService.class),conn,Context.BIND_IMPORTANT);
}
private void show() {
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
Toast.makeText(LocalService.this, "本地服务正常", Toast.LENGTH_SHORT).show();
super.handleMessage(msg);
}
};
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
};
timer.schedule(task, 2000, 2000);
}
}
(3)创建一个RomoteService服务分别实现aidl接口的调用
public class RomoteService extends Service{
MyConn conn;
MyBinder binder;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
@Override
public void onCreate() {
super.onCreate();
conn = new MyConn();
binder = new MyBinder();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
show();
Toast.makeText(this, " 远程服务活了", Toast.LENGTH_SHORT).show();
this.bindService(new Intent(this, LocalService.class), conn, Context.BIND_IMPORTANT);
return START_STICKY;
}
class MyBinder extends IServiceAidlInterface.Stub {
@Override
public String getServiceName() throws RemoteException {
return RomoteService.class.getSimpleName();
}
}
class MyConn implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("box", "绑定本地服务成功");
// Toast.makeText(RomoteService.this, "绑定本地服务成功", Toast.LENGTH_SHORT).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("box", "本地服务被干掉了");
Toast.makeText(RomoteService.this, "本地服务挂了", Toast.LENGTH_SHORT).show();
//开启本地服务
RomoteService.this.startService(new Intent(RomoteService.this, LocalService.class));
//绑定本地服务
RomoteService.this.bindService(new Intent(RomoteService.this, LocalService.class), conn, Context.BIND_IMPORTANT);
}
}
@Override
public void onDestroy() {
super.onDestroy();
//开启本地服务
RomoteService.this.startService(new Intent(RomoteService.this, LocalService.class));
//绑定本地服务
RomoteService.this.bindService(new Intent(RomoteService.this, LocalService.class), conn,Context.BIND_IMPORTANT);
}
private void show() {
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
Toast.makeText(RomoteService.this, "远程服务正常", Toast.LENGTH_SHORT).show();
super.handleMessage(msg);
}
};
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
Message message = new Message();
message.what = 1;
handler.sendMessage(message);
}
};
timer.schedule(task, 2000, 2000);
}
}
(4)可以监听系统的某些动作来实现监听,判断LocalService和RomoteService是否还在进行,这儿我写了一个工具类判断当前服务是否还在进行和判断当前包名是否也还在进行当中
/**
* 判断本应用是否存活
* 如果需要判断本应用是否在后台还是前台用getRunningTask
*/
public static boolean isAPPALive(Context mContext, String packageName) {
boolean isAPPRunning = false;
// 获取activity管理对象
ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
// 获取所有正在运行的app
List<ActivityManager.RunningAppProcessInfo> appProcessInfoList = activityManager.getRunningAppProcesses();
// 遍历,进程名即包名
for (ActivityManager.RunningAppProcessInfo appInfo : appProcessInfoList) {
if (packageName.equals(appInfo.processName)) {
isAPPRunning = true;
break;
}
}
return isAPPRunning;
}
/**
* 判断某个服务是否正在运行的方法
*
* @param serviceName 是包名+服务的类名(例如:net.loonggg.testbackstage.TestService)
* @return true代表正在运行,false代表服务没有正在运行
*/
public static boolean serviceAlive(Context context, String serviceName) {
boolean isWork = false;
ActivityManager myAM = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> myList = myAM.getRunningServices(100);
if (myList.size() <= 0) {
return false;
}
for (int i = 0; i < myList.size(); i++) {
String mName = myList.get(i).service.getClassName().toString();
if (mName.equals(serviceName)) {
isWork = true;
break;
}
}
return isWork;
}
(5).可以创建单个的1像素Activity在页面监听
public class SinglePixelActivity extends AppCompatActivity {
private static final String TAG = "SinglePixelActivity";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate--->启动1像素保活");
Window mWindow = getWindow();
mWindow.setGravity(Gravity.LEFT | Gravity.TOP);
WindowManager.LayoutParams attrParams = mWindow.getAttributes();
attrParams.x = 0;
attrParams.y = 0;
attrParams.height = 300;
attrParams.width = 300;
mWindow.setAttributes(attrParams);
// 绑定SinglePixelActivity到ScreenManager
ScreenManager.getScreenManagerInstance(this).setSingleActivity(this);
}
锁屏工具类
public class ScreenReceiverUtil {
private Context mContext;
// 锁屏广播接收器
private SreenBroadcastReceiver mScreenReceiver;
// 屏幕状态改变回调接口
private SreenStateListener mStateReceiverListener;
public ScreenReceiverUtil(Context mContext){
this.mContext = mContext;
}
public void setScreenReceiverListener(SreenStateListener mStateReceiverListener){
this.mStateReceiverListener = mStateReceiverListener;
// 动态启动广播接收器
this.mScreenReceiver = new SreenBroadcastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
mContext.registerReceiver(mScreenReceiver,filter);
}
public void stopScreenReceiverListener(){
mContext.unregisterReceiver(mScreenReceiver);
}
public class SreenBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d("KeepAppAlive","SreenLockReceiver-->监听到系统广播:"+action);
if(mStateReceiverListener == null){
return;
}
if(Intent.ACTION_SCREEN_ON.equals(action)){ // 开屏
mStateReceiverListener.onSreenOn();
}else if(Intent.ACTION_SCREEN_OFF.equals(action)){ // 锁屏
mStateReceiverListener.onSreenOff();
}else if(Intent.ACTION_USER_PRESENT.equals(action)){ // 解锁
mStateReceiverListener.onUserPresent();
}
}
}
// 监听sreen状态对外回调接口
public interface SreenStateListener {
void onSreenOn();
void onSreenOff();
void onUserPresent();
}
}
2.针对于android中7.0以上的手机采用jobservice
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class JobWakeUpService extends JobService {
private int JobWakeUpId = 1;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//开启轮寻
JobInfo.Builder mJobBulider = new JobInfo.Builder(
JobWakeUpId, new ComponentName(this, JobWakeUpService.class));
// //设置轮寻时间
mJobBulider.setPeriodic(15 * 60 * 1000);
//系统当你的设备重启之后你的任务是否还要继续执行
mJobBulider.setPersisted(true); // 设置设备重启时,执行该任务
mJobBulider.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
mJobBulider.setRequiresCharging(true); // 当插入充电器,执行该任务
JobScheduler mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo info = mJobBulider.build();
mJobScheduler.schedule(info); //开始定时执行该系统任务
return START_STICKY;
}
@Override
public boolean onStartJob(JobParameters jobParameters) {
Log.e("aa", "-----------onStartJob-------");
//开启定时任务 定时轮寻 判断应用Service是否被杀死
//如果被杀死则重启Service
mJobHandler.sendMessage(Message.obtain(mJobHandler, 1, jobParameters));
return false;
}
@Override
public boolean onStopJob(JobParameters jobParameters) {
Log.e("aa", "-----------onStopJob-------");
mJobHandler.removeMessages(1);
return true;
}
private Handler mJobHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
//这儿是列举的获取数据这样传递值过去的
Intent intent = new Intent();
intent.putExtra(AppHawkey.LONGITUDE_KEY, longitude);
intent.putExtra(AppHawkey.LATITUDE_KEY, latitude);
LocationService.enqueueWork(getApplicationContext(), intent);
jobFinished((JobParameters) msg.obj, false);
return true;
}
});
对了针对于上面的你在service中获取的数据最好是用JobIntentService,具体原因是抛了一个错误,crash
java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.xxx.xx/.core.service.NotifyJobService }: app is in background uid UidRecord{6dd5849 u0a172 TPSL idle change:idle|cached procs:1 seq(0,0,0)}
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1628)
at android.app.ContextImpl.startService(ContextImpl.java:1569)
at android.content.ContextWrapper.startService(ContextWrapper.java:675)
at com.xxx.xx.application.MainApp.onCreate(Unknown Source:385)
at com.baidu.protect.A.a(Native Method)
at com.baidu.protect.StubApplication.onCreate(StubApplication.java:296)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1154)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:6273) ... 8 more
在android系统8.0以上适配请添加以下权限
使用示例:
1.在Manifest中声名Permission:<uses-permission android:name="android.permission.WAKE_LOCK" />
2.在Manifest中声名Service:
<service android:name=".service.LocationService"
android:permission="android.permission.BIND_JOB_SERVICE"
/>
3.实现JobIntentService类:
public class LocationService extends JobIntentService {
/**
* 这个Service 唯一的id
*/
static final int JOB_ID = 10111;
/**
* Convenience method for enqueuing work in to this service.
*/
static void enqueueWork(Context context, Intent work) {
enqueueWork(context, LocationService.class, JOB_ID, work);
LocationUtil.isOpen=true;
}
@Override
protected void onHandleWork(@NonNull Intent intent) {
double longitude = intent.getDoubleExtra(AppHawkey.LONGITUDE_KEY, 0.00);
double latitude = intent.getDoubleExtra(AppHawkey.LATITUDE_KEY, 0.00);
LogUtil.e("-------longitude------" + longitude);
LogUtil.e("-------latitude------" + latitude);
String locationKey = PreferenceUtils.getString(AppHawkey.LOCATION_SAVE_KEY, "");
if (!TextUtils.isEmpty(locationKey)) {
UploadLoaction loaction = JsonUtil.fromJson(locationKey, UploadLoaction.class);
if (loaction.getLocations() != null && loaction != null) {
List<UploadLoaction.location> data = new ArrayList<>();
data.addAll(loaction.getLocations());
UploadLoaction.location item = new UploadLoaction.location();
item.setLongitude(longitude);
item.setLatitude(latitude);
data.add(item);
loaction.setLocations(data);
String toJson = JsonUtil.toJson(loaction);
toast(toJson);
PreferenceUtils.setString(AppHawkey.LOCATION_SAVE_KEY, toJson);
}
} else {
UploadLoaction loaction = new UploadLoaction();
List<UploadLoaction.location> data = new ArrayList<>();
UploadLoaction.location item = new UploadLoaction.location();
item.setLatitude(latitude);
item.setLongitude(longitude);
data.add(item);
loaction.setLocations(data);
String toJson = JsonUtil.toJson(loaction);
toast(toJson);
PreferenceUtils.setString(AppHawkey.LOCATION_SAVE_KEY, toJson);
}
}
final Handler mHandler = new Handler();
// Helper for showing tests
void toast(final CharSequence text) {
mHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(LocationService.this, text, Toast.LENGTH_SHORT).show();
}
});
}
}