• 进程优先级
  • 提升进程优先级
  • 方法一启动一个1像素的activity
  • 方法二双进程守护可以防止单个进程杀死同时可以防止第三方的360清理掉一个进程被杀死另外一个进程又被他启动相互监听启动杀进程是一个一个杀的本质是和杀进程时间赛跑这里跨进程通信采用AIDL


android开发时,一般用service处理后台任务。当系统进程空间紧张的时候,会依照优先级自动进行进程的回收。

进程优先级

1.前台进程:Foreground process。

  • 用户正在交互的Activity(onResume())
  • 当某个Service绑定正在交互的Activity
  • 被主动调用为前台Service(startForeground())
  • 组件正在执行生命周期的回调(onCreate()/onStart()/onDestroy())
  • BroadcastReceiver 正在执行onReceive()

2.可见进程:Visible process

  • Activity处在onPause()(没有进入onStop())
  • 绑定到前台Activity的Service

3.服务进程:Service process

  • 简单的startService()启动

4.后台进程:Background process

  • 对用户没有直接影响的进程—-Activity出于onStop()的时候
  • android:process=”:xxx”

5.空进程:Empty process

  • 不含有任何的活动的组件。(android设计的,为了第二次启动更快,采取的一个权衡)

提升进程优先级

方法一:启动一个1像素的activity

1.创建一个1像素的activity的透明的activity

Window window = getWindow();
window.setGravity(Gravity.LEFT|Gravity.TOP);
LayoutParams params = window.getAttributes();
params.height = 1;
params.width = 1;
params.x = 0;
params.y = 0;   
window.setAttributes(params);


<item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowFrame">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:backgroundDimEnabled">false</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowAnimationStyle">@null</item>
        <item name="android:windowDisablePreview">true</item>
        <item name="android:windowNoDisplay">false</item>

2.创建监听开屏、解锁、锁屏的广播,并回调

private class ScreenBroadcastReceiver extends BroadcastReceiver {
        private String action = null;
        @Override
        public void onReceive(Context context, Intent intent) {
            action = intent.getAction();
            if (Intent.ACTION_SCREEN_ON.equals(action)) { // 开屏
                mScreenStateListener.onScreenOn();
            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) { // 锁屏
                mScreenStateListener.onScreenOff();
            } else if (Intent.ACTION_USER_PRESENT.equals(action)) { // 解锁
                mScreenStateListener.onUserPresent();
            }
        }
    }

private void registerListener() {
        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 interface ScreenStateListener {// 返回给调用者屏幕状态信息
        public void onScreenOn();
        public void onScreenOff();
        public void onUserPresent();
    }

3.创建Service执行监听任务

@Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        ScreenListener listener = new ScreenListener(this);
        listener.begin(new ScreenStateListener() {
            @Override
            public void onUserPresent() {
            }
            @Override
            public void onScreenOn() {
                // 开屏---finish这个一个像素的Activity
            }       
            @Override
            public void onScreenOff() {
                // 锁屏---启动一个像素的Activity
            }
        });
    }

方法二:双进程守护,可以防止单个进程杀死,同时可以防止第三方的360清理掉。一个进程被杀死,另外一个进程又被他启动,相互监听启动。杀进程是一个一个杀的,本质是和杀进程时间赛跑。这里跨进程通信采用AIDL。

1.开辟一个本地进程,编写接口以及方法

<service 
    android:name="xxxx"
    android:process=":remoteprocess">
</service>

2.创建Service与本地进程通信,再创建一个Service相互监听,两个service代码逻辑一样

private MyBinder binder;
    private MyServiceConnection conn;
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }
    @Override
    public void onCreate() {
        super.onCreate();
        if(binder ==null){
            binder = new MyBinder();
        }
        conn = new MyServiceConnection();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LocalService.this.bindService(new Intent(LocalService.this, RemoteService.class), conn, Context.BIND_IMPORTANT);
        PendingIntent contentIntent = PendingIntent.getService(this, 0, intent, 0);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setTicker("360")
        .setContentIntent(contentIntent)
        .setContentTitle("我是360,我怕谁!")
        .setAutoCancel(true)
        .setContentText("hehehe")
        .setWhen( System.currentTimeMillis());
        //把service设置为前台运行,避免手机系统自动杀掉改服务。
        startForeground(startId, builder.build());
        return START_STICKY;
    }


    class MyBinder extends RemoteConnection.Stub{
        @Override
        public String getProcessName() throws RemoteException {
            return "LocalService";
        }
    }

    class MyServiceConnection implements ServiceConnection{
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i(TAG, "建立连接成功!");
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i(TAG, "RemoteService服务被干掉了~~~~断开连接!");
            Toast.makeText(LocalService.this, "断开连接", 0).show();
            //启动被干掉的
            LocalService.this.startService(new Intent(LocalService.this, RemoteService.class));
            LocalService.this.bindService(new Intent(LocalService.this, RemoteService.class), conn, Context.BIND_IMPORTANT);
        }
    }

3.最后再来个恐怖的,利用JobScheduler每隔多少秒去判断服务有没有在运行,没有就启动服务,这样几乎就杀不死了。

private int kJobId = 0;
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("INFO", "jobService create");

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("INFO", "jobService start");
        scheduleJob(getJobInfo());
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
    }

    @Override
    public boolean onStartJob(JobParameters params) {
        // TODO Auto-generated method stub
        Log.i("INFO", "job start");
//      scheduleJob(getJobInfo());
        boolean isLocalServiceWork = isServiceWork(this, "com.dn.keepliveprocess.LocalService");
        boolean isRemoteServiceWork = isServiceWork(this, "com.dn.keepliveprocess.RemoteService");
//      Log.i("INFO", "localSericeWork:"+isLocalServiceWork);
//      Log.i("INFO", "remoteSericeWork:"+isRemoteServiceWork);
        if(!isLocalServiceWork||
           !isRemoteServiceWork){
            this.startService(new Intent(this,LocalService.class));
            this.startService(new Intent(this,RemoteService.class));
            Toast.makeText(this, "process start", Toast.LENGTH_SHORT).show();
        }
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        Log.i("INFO", "job stop");
//      Toast.makeText(this, "process stop", Toast.LENGTH_SHORT).show();
        scheduleJob(getJobInfo());
        return true;
    }

    /** Send job to the JobScheduler. */
    public void scheduleJob(JobInfo t) {
        Log.i("INFO", "Scheduling job");
        JobScheduler tm =
                (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
        tm.schedule(t);
    }

    public JobInfo getJobInfo(){
        JobInfo.Builder builder = new JobInfo.Builder(kJobId++, new ComponentName(this, JobHandleService.class));
        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
        builder.setPersisted(true);
        builder.setRequiresCharging(false);
        builder.setRequiresDeviceIdle(false);
        builder.setPeriodic(10);//间隔时间--周期
        return builder.build();
    }


    /** 
     * 判断某个服务是否正在运行的方法 
     *  
     * @param mContext 
     * @param serviceName 
     *            是包名+服务的类名(例如:net.loonggg.testbackstage.TestService) 
     * @return true代表正在运行,false代表服务没有正在运行 
     */  
    public boolean isServiceWork(Context mContext, String serviceName) {  
        boolean isWork = false;  
        ActivityManager myAM = (ActivityManager) mContext  
                .getSystemService(Context.ACTIVITY_SERVICE);  
        List<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;  
    }