安卓进程进程保活分为:
黑色保活,白色保活,灰色保活
黑色保活:
可以说黑色保活,可以通过网络切换,拍照,拍视频,开机,利用系统产生的广播唤醒app,接入三方的sdk也会唤醒一些app,如支付宝,微信..........这样的话,这样的话,不敢想象系统存活会给系统带来多大的负担,所以我们的安卓手机也变得卡了,google官方可能也认识了这么一点,所以取消了
ACTION_NEW_PICTURE(拍照),ACTION_NEW_VIDEO(拍视频),CONNECTIVITY_ACTION(网络切换)
app也会随着做一点改变,(不过sdk的使用还是会通过一个app启动相关的一些app , 黑色保活我个人认为不推荐使用,毕竟为了我们广大安卓用户。)
白色保活:
白色保活手段非常简单,就是调用系统api启动一个前台的Service进程,这样会在系统的通知栏生成一个Notification,用来让用户知道有这样一个app在运行着,哪怕当前的app退到了后台。
不过用户看到这个图标的时候,都会把它清空的。。。。
灰色保活:
可以说,灰色保活是用的最多,当用户不知不觉中这个app程序已经在后台运行了。
它是利用系统的漏洞来启动一个前台的Service进程,与普通的启动方式区别在于,它不会在系统通知栏处出现一个Notification,看起来就如同运行着一个后台Service进程一样。这样做带来的好处就是,用户无法察觉到你运行着一个前台进程(因为看不到Notification),但你的进程优先级又是高于普通后台进程的。API < 18,启动前台Service时直接传入new Notification();API >= 18,同时启动两个id相同的前台Service,然后再将后启动的Service做stop处理;
安卓app唤醒:
其实app唤醒的介绍很好说,app唤醒就是当打开一个app的时候,另一个app里有对应刚打开那个app的属性标志,根据你想要的唤醒方式,执行不同的代码操作,这样就可以唤醒另一个没打开的app了。(代码在最下面)
下面我展示一下这几种状态下的代码:
这个是xml布局,主要是为了展示我所介绍的几种保活方式:
下面是主要实现类:
WakeReceiver
import android.app.Notification;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
public class WakeReceiver extends BroadcastReceiver {
private final static String TAG = WakeReceiver.class.getSimpleName();
private final static int WAKE_SERVICE_ID = -1111;
/**
* 灰色保活手段唤醒广播的action
*/
public final static String GRAY_WAKE_ACTION = "com.wake.gray";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (GRAY_WAKE_ACTION.equals(action)) {
Log.i(TAG, "wake !! wake !! ");
Intent wakeIntent = new Intent(context, WakeNotifyService.class);
context.startService(wakeIntent);
}
}
/**
* 用于其他进程来唤醒UI进程用的Service
*/
public static class WakeNotifyService extends Service {
@Override
public void onCreate() {
Log.i(TAG, "WakeNotifyService->onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "WakeNotifyService->onStartCommand");
if (Build.VERSION.SDK_INT < 18) {
startForeground(WAKE_SERVICE_ID, new Notification());//API < 18 ,此方法能有效隐藏Notification上的图标
} else {
Intent innerIntent = new Intent(this, WakeGrayInnerService.class);
startService(innerIntent);
startForeground(WAKE_SERVICE_ID, new Notification());
}
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onDestroy() {
Log.i(TAG, "WakeNotifyService->onDestroy");
super.onDestroy();
}
}
/**
* 给 API >= 18 的平台上用的灰色保活手段
*/
public static class WakeGrayInnerService extends Service {
@Override
public void onCreate() {
Log.i(TAG, "InnerService -> onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "InnerService -> onStartCommand");
startForeground(WAKE_SERVICE_ID, new Notification());
//stopForeground(true);
stopSelf();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onDestroy() {
Log.i(TAG, "InnerService -> onDestroy");
super.onDestroy();
}
}
}
BackGroundService
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
/**
* 普通的后台Service进程
*
* @author clock
* @since 2016-04-12
*/
public class BackgroundService extends Service {
private final static String TAG = BackgroundService.class.getSimpleName();
@Override
public void onCreate() {
Log.i(TAG, "onCreate");
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onDestroy() {
Log.i(TAG, "onDestroy");
super.onDestroy();
}
}
GrayService
import android.app.AlarmManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import com.example.renzheng.receiver.WakeReceiver;
/**
* 灰色保活手法创建的Service进程
*
* @author Clock
* @since 2016-04-12
*/
public class GrayService extends Service {
private final static String TAG = GrayService.class.getSimpleName();
/**
* 定时唤醒的时间间隔,5分钟
*/
private final static int ALARM_INTERVAL = 5 * 60 * 1000;
private final static int WAKE_REQUEST_CODE = 6666;
private final static int GRAY_SERVICE_ID = -1001;
@Override
public void onCreate() {
Log.i(TAG, "GrayService->onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "GrayService->onStartCommand");
if (Build.VERSION.SDK_INT < 18) {
startForeground(GRAY_SERVICE_ID, new Notification());//API < 18 ,此方法能有效隐藏Notification上的图标
} else {
Intent innerIntent = new Intent(this, GrayInnerService.class);
startService(innerIntent);
startForeground(GRAY_SERVICE_ID, new Notification());
}
//发送唤醒广播来促使挂掉的UI进程重新启动起来
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent();
alarmIntent.setAction(WakeReceiver.GRAY_WAKE_ACTION);
PendingIntent operation = PendingIntent.getBroadcast(this, WAKE_REQUEST_CODE, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), ALARM_INTERVAL, operation);
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onDestroy() {
Log.i(TAG, "GrayService->onDestroy");
super.onDestroy();
}
/**
* 给 API >= 18 的平台上用的灰色保活手段
*/
public static class GrayInnerService extends Service {
@Override
public void onCreate() {
Log.i(TAG, "InnerService -> onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "InnerService -> onStartCommand");
startForeground(GRAY_SERVICE_ID, new Notification());
//stopForeground(true);
stopSelf();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onDestroy() {
Log.i(TAG, "InnerService -> onDestroy");
super.onDestroy();
}
}
}
WhileService
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
import com.example.renzheng.MainActivity;
import com.example.renzheng.R;
/**
* 正常的系统前台进程,会在系统通知栏显示一个Notification通知图标
*
* @author clock
* @since 2016-04-12
*/
public class WhiteService extends Service {
private final static String TAG = WhiteService.class.getSimpleName();
private final static int FOREGROUND_ID = 1000;
@Override
public void onCreate() {
Log.i(TAG, "WhiteService->onCreate");
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "WhiteService->onStartCommand");
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("Foreground");
builder.setContentText("I am a foreground service");
builder.setContentInfo("Content Info");
builder.setWhen(System.currentTimeMillis());
Intent activityIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, activityIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
Notification notification = builder.build();
startForeground(FOREGROUND_ID, notification);
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onDestroy() {
Log.i(TAG, "WhiteService->onDestroy");
super.onDestroy();
}
}
MainActivity
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import com.example.renzheng.service.BackgroundService;
import com.example.renzheng.service.GrayService;
import com.example.renzheng.service.WhiteService;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private final static String TAG = MainActivity.class.getSimpleName();
/**
* 黑色唤醒广播的action
*/
private final static String BLACK_WAKE_ACTION = "com.wake.black";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.mBtn_white).setOnClickListener(this);
findViewById(R.id.mBtn_gray).setOnClickListener(this);
findViewById(R.id.mBtn_black).setOnClickListener(this);
findViewById(R.id.mBtn_background_service).setOnClickListener(this);
}
@Override
public void onClick(View v) {
int viewId = v.getId();
if (viewId == R.id.mBtn_white) { //系统正常的前台Service,白色保活手段
Intent whiteIntent = new Intent(getApplicationContext(), WhiteService.class);
startService(whiteIntent);
} else if (viewId == R.id.mBtn_gray) {//利用系统漏洞,灰色保活手段(API < 18 和 API >= 18 两种情况)
Intent grayIntent = new Intent(getApplicationContext(), GrayService.class);
startService(grayIntent);
} else if (viewId == R.id.mBtn_black) { //拉帮结派,黑色保活手段,利用广播唤醒队友
Intent blackIntent = new Intent();
blackIntent.setAction(BLACK_WAKE_ACTION);
sendBroadcast(blackIntent);
} else if (viewId == R.id.mBtn_background_service) {//普通的后台进程
Intent bgIntent = new Intent(getApplicationContext(), BackgroundService.class);
startService(bgIntent);
}
}
}
代码注册权限:
下面是app唤醒代码:
有2个APP,分别为A和B,当A活着的时候,试着开启B的后台服务,将原本杀死的B的后台服务程序活起来。反之也一样。
1.先看B的代码:
创建一个服务B,给服务添加一个process属性,设置action。
B的代码,在onStartCommand方法中弹出toast:
public class B extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "B 已经唤醒", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
}
2.看A的代码,在MainActivity中点击开启B应用的B服务的代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendService();
}
});
}
private void sendService() {
boolean find = false;
ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
Intent serviceIntent = new Intent();
for (ActivityManager.RunningServiceInfo runningServiceInfo : mActivityManager.getRunningServices(100)) {
if (runningServiceInfo.process.contains(":test")) {//判断service是否在运行
Log.e("zhang", "process:" + runningServiceInfo.process);
find = true;
}
}
//判断服务是否起来,如果服务没起来,就唤醒
if (!find) {
serviceIntent.setPackage("com.example.b);
serviceIntent.setAction("yangyang");
startService(serviceIntent);
Toast.makeText(this, "开始唤醒 B", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this, "B 不用唤醒", Toast.LENGTH_SHORT).show();
}
}
}
这里只是写了A启动B服务的代码,反之也是一样的。被启动应用的Servcie在AndroidMainfest.xml中注册时注意,添加process属性,和设置action匹配规则。