精华内容
下载资源
问答
  • Android Service保活方法总结(不被杀死)进程守护

    万次阅读 多人点赞 2018-01-08 21:04:50
    保活Service我们需要做什么: 1.在应用被关闭后保活(最难) 2.在内用占用过大,系统自动释放内存时保活(优先杀死占用较高的Service) 3.重启手机后自动开启Service 4.手机息屏后不被释放内存 5.手动清理内存...

     

    写在前头

    保活Service我们需要做什么:

    1.在应用被关闭后保活(最难)

    2.在内用占用过大,系统自动释放内存时保活(优先杀死占用较高的Service)

    3.重启手机后自动开启Service

    4.手机息屏后不被释放内存

    5.手动清理内存时保活

     

    首先介绍一下Service的等级:

    一、前台进程
    二、可见进程
    三、服务进程
    四、后台进程
    五、空进程  ---关闭应用后,没有清理缓存

    所以为了提高优先级我们可以使用startForeground()方法将Service设置为前台进程。

     

    一、在AndroidManifest中添加Service

    <service android:name=".modle.StepService"
                android:process="istep.service"  //放入新进程
                >
                <intent-filter android:priority="1000">
                    <!-- 系统启动完成后会调用-->
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                    <action android:name="android.intent.action.DATE_CHANGED"/>
                    <action android:name="android.intent.action.MEDIA_MOUNTED" />
                    <action android:name="android.intent.action.USER_PRESENT" />
                    <action android:name="android.intent.action.ACTION_TIME_TICK" />
                    <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
                </intent-filter>
    </service>
    
    
    <service android:name=".modle.GuardService"
                android:process=":GuardService">
                <intent-filter >
                    <!-- 系统启动完成后会调用-->
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                    <action android:name="android.intent.action.DATE_CHANGED"/>
                    <action android:name="android.intent.action.MEDIA_MOUNTED" />
                    <action android:name="android.intent.action.USER_PRESENT" />
                    <action android:name="android.intent.action.ACTION_TIME_TICK" />
                    <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
                </intent-filter>
            </service>
    

     

    二、双进程保护

    1.创建aidl实现跨进程通信(新建一个aidl)

     

    interface ProcessConnection {
        /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
        //删除不必要方法
     }
    

     

    2.创建主服务

    /**
     * 主进程 双进程通讯
     * Created by db on 2018/1/11.
     */
    
    public class StepService extends Service{
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return new ProcessConnection.Stub() {};
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startForeground(1,new Notification());
            //绑定建立链接
            bindService(new Intent(this,GuardService.class),
                    mServiceConnection, Context.BIND_IMPORTANT);
            return START_STICKY;
        }
    
        private ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                //链接上
                Log.d("test","StepService:建立链接");
            }
    
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                //断开链接
                startService(new Intent(StepService.this,GuardService.class));
                //重新绑定
                bindService(new Intent(StepService.this,GuardService.class),
                        mServiceConnection, Context.BIND_IMPORTANT);
            }
        };
    
    }
    

     

    3.创建守护服务

     /**
     * 守护进程 双进程通讯
     * Created by db on 2018/1/11.
     */
    
    public class GuardService extends Service{
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return new ProcessConnection.Stub() {};
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startForeground(1,new Notification());
            //绑定建立链接
            bindService(new Intent(this,StepService.class),
                    mServiceConnection, Context.BIND_IMPORTANT);
            return START_STICKY;
        }
    
        private ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                //链接上
                Log.d("test","GuardService:建立链接");
            }
    
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                //断开链接
                startService(new Intent(GuardService.this,StepService.class));
                //重新绑定
                bindService(new Intent(GuardService.this,StepService.class),
                        mServiceConnection, Context.BIND_IMPORTANT);
            }
        };
    
    }
    
    

     

    返回参数含义:

     

    • START_STICKY:在Service被关闭后,重新开启Service
    • START_NOT_STICKY:服务被异常杀掉后,系统将会被设置为started状态,系统不会重启该服务,直到startService(Intent intent)方法再次被调用。
    • START_REDELIVER_INTENT:重传Intent,使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
    • START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

     

    三、使用JobService来实现应用退出后重启Service

     

    1、在AndroidManifest中添加Service和权限

    <!--JobService权限-->
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <receiver android:name=".modle.BootCompleteReceiver">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                </intent-filter>
    </receiver>

    2、JobService代码

    /**
     * 用于判断Service是否被杀死
     * Created by db on 2018/1/11.
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)//5.0以后可用
    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(2000);
            JobScheduler mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
            mJobScheduler.schedule(mJobBulider.build());
            return START_STICKY;
        }
    
        @Override
        public boolean onStartJob(JobParameters jobParameters) {
            //开启定时任务 定时轮寻 判断应用Service是否被杀死
            //如果被杀死则重启Service
            boolean messageServiceAlive = serviceAlive(StepService.class.getName());
            if(!messageServiceAlive){
                startService(new Intent(this,StepService.class));
            }
    
            return false;
        }
    
        @Override
        public boolean onStopJob(JobParameters jobParameters) {
    
            return false;
        }
    
        /**
         * 判断某个服务是否正在运行的方法
         * @param serviceName
         *            是包名+服务的类名(例如:net.loonggg.testbackstage.TestService)
         * @return true代表正在运行,false代表服务没有正在运行
         */
        private boolean serviceAlive(String serviceName) {
            boolean isWork = false;
            ActivityManager myAM = (ActivityManager)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;
        }
    }

     

    四、保证Service在开机后自动启动

    (1)注册广播

      <receiver android:name=".modle.mReceiver">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                </intent-filter>
      </receiver>

    (2)广播代码

    /**
     * 开机完成广播
     */
    
    public class mReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent){
            Intent mIntent = new Intent(context,StepService.class);
            context.startService(mIntent);
        }
    }
    

     

    五、保证息屏后不被释放资源杀死(WakeLock的使用)

    (1)添加权限

        <uses-permission android:name="android.permission.WAKE_LOCK" />

    (2)在创建Service以后调用方法

       /**
         * 同步方法   得到休眠锁
         * @param context
         * @return
         */
        synchronized private void getLock(Context context){
            if(mWakeLock==null){
                PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
                mWakeLock=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,StepService.class.getName());
                mWakeLock.setReferenceCounted(true);
                Calendar c=Calendar.getInstance();
                c.setTimeInMillis((System.currentTimeMillis()));
                int hour =c.get(Calendar.HOUR_OF_DAY);
                if(hour>=23||hour<=6){
                    mWakeLock.acquire(5000);
                }else{
                    mWakeLock.acquire(300000);
                }
            }
            Log.v(TAG,"get lock");
        }
    

    (3)在onDestroy()方法中调用释放锁的方法(避免占用内存)

    synchronized private void releaseLock()
        {
            if(mWakeLock!=null){
                if(mWakeLock.isHeld()) {
                    mWakeLock.release();
                    Log.v(TAG,"release lock");
                }
    
                mWakeLock=null;
            }
        }
    PARTIAL_WAKE_LOCK保持CPU运转,屏幕和键盘灯有可能是关闭的。
    SCREEN_DIM_WAKE_LOCK保持CPU运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯。
    SCREEN_BRIGHT_WAKE_LOCK保持CPU运转,保持屏幕高亮显示,允许关闭键盘灯。
    FULL_WAKE_LOCK保持CPU运转,保持屏幕高亮显示,键盘灯也保持亮度。
    ACQUIRE_CAUSES_WAKEUP不会唤醒设备,强制屏幕马上高亮显示,键盘灯开启。有一个例外,如果有notification弹出的话,会唤醒设备。
    ON_AFTER_RELEASEWake Lock被释放后,维持屏幕亮度一小段时间,减少Wake Lock循环时的闪烁情况。

     

     

    六、启动所有Service(在Activity中)

       /**
         * 开启所有Service
         */
        private void startAllServices()
        {
            startService(new Intent(this, StepService.class));
            startService(new Intent(this, GuardService.class));
            if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.LOLLIPOP) {
                Log.d(TAG, "startAllServices: ");
                //版本必须大于5.0
                startService(new Intent(this, JobWakeUpService.class));
            }
        }

     

    注意:该方法不能保证在所有机型上有效,而且除非在必要时,否则不建议写这样的流氓软件。特别是谷歌在android7.0以后对管理加强,想要保活Service其实已经变得不太可能了,谷歌这样做无疑是为了减少流氓软件的数量,这样做也是可取的。
     

     

     

     

    展开全文
  • Android进程守护service保活

    千次阅读 2016-12-19 23:44:17
    android应用进程保活可以从以下来年个方面考虑 1、尽量保证应用进程不被杀死。 2、进程被杀死后能够复活。 要保证进程不被杀死是不可能的,系统在资源紧缺的情况下回根据进程优先等级杀掉有限等级比较低的进程,...
     
    


    android应用进程保活可以从以下来年个方面考虑
    1、尽量保证应用进程不被杀死。
    2、进程被杀死后能够复活。
    要保证进程不被杀死是不可能的,系统在资源紧缺的情况下回根据进程优先等级杀掉有限等级比较低的进程,所以为了使自己的进程不易于被系统杀死,只能提高进程的优先级,这个进程重要性的层次结构有五个等级,按高到低分为
    1)前台进程 Foreground process
    2)可见进程 Visible process
    3)服务进程 Service process
    4)后台进程 Background process
    5)空进程 Empty process
    Android的service置为前台startForeground,这样就提高了service的优先级。
    系统总会在某个时刻因为某些原因把你杀掉,被杀掉不可怕,可怕的是被杀掉后就再也活不过来了,so我们得制定各种策略,好让进程能在被杀后可以自启。进程被杀死后重启复活我们通过双进程守护可以是可以做到的,通过双进程守护可以在大部分情况下做到进程保活,手动清理和360等第三方软件的清理仍可以保活,对于要求比较高的场合,双进程守护是不够的,还要进行更深入的研究,系统清理进程不在本文的考虑范围之内,有兴趣的朋友可以自己去深入研究。
    双进程守护的实现:
    在应用中开启两个Service分别为LocalService和RemoteService,通过aidl相互绑定,只要其中一个呗杀死则通过另一个重启对方,这就保证了Service保活,关键的一点事LocalService和RemoteService必须要在两个不同的而进程中,我们可以通过在AndroidManifest.xml配置文件中定义
      <service android:name=".LocalService" />
      <service android:name=".RemoteService" android:process=":remote"/>
    android:process=":remote"可以保证RemoteService运行在另外一个进程中。
    下面贴出双进程守护保活的demo代码,供参考
    在包路径下定义aidl文件夹aidl
    在文件夹下定义Guard.aidl文件

    package com.guardservice.aidl;
    interface GuardAidl{
        void doSomething();
    }

    本地服务LocalService.java

    package com.guardservice;
    
    import com.guardservice.aidl.GuardAidl;
    import android.app.Notification;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.util.Log;
    
    public class LocalService extends Service {
    
    	private MyBilder mBilder;
    
    	@Override
    	public IBinder onBind(Intent intent) {
    		if (mBilder == null)
    			mBilder = new MyBilder();
    
    		return mBilder;
    
    	}
    
    	@Override
    	public void onStart(Intent intent, int startId) {
    		super.onStart(intent, startId);
    
    	}
    
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId) {
    		this.bindService(new Intent(LocalService.this, RemoteService.class),
    				connection, Context.BIND_ABOVE_CLIENT);
    
    		Notification notification = new Notification(R.drawable.ic_launcher,
    				"安全服务启动中", System.currentTimeMillis());
    		PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent,
    				0);
    		notification.setLatestEventInfo(this, "安全服务", "安全服务...", pendingIntent);
    		startForeground(startId, notification);
    		
    		return START_STICKY;
    	}
    
    	private class MyBilder extends GuardAidl.Stub {
    
    		@Override
    		public void doSomething() throws RemoteException {
    			Log.i("TAG", "绑定成功!");
    			Intent localService = new Intent(LocalService.this,
    					RemoteService.class);
    			LocalService.this.startService(localService);
    			LocalService.this
    					.bindService(new Intent(LocalService.this,
    							RemoteService.class), connection,
    							Context.BIND_ABOVE_CLIENT);
    		}
    
    	}
    
    	private ServiceConnection connection = new ServiceConnection() {
    
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    			Log.i("TAG", "RemoteService被杀死了");
    			Intent localService = new Intent(LocalService.this,
    					RemoteService.class);
    			LocalService.this.startService(localService);
    			LocalService.this
    					.bindService(new Intent(LocalService.this,
    							RemoteService.class), connection,
    							Context.BIND_ABOVE_CLIENT);
    		}
    
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    			Log.i("TAG", "RemoteService链接成功!");
    			try {
    				if (mBilder != null)
    					mBilder.doSomething();
    			} catch (RemoteException e) {
    				e.printStackTrace();
    			}
    		}
    	};
    
    }
    

    
    

    远程服务RemoteService.java

    package com.guardservice;
    
    import com.guardservice.aidl.GuardAidl;
    import android.app.Notification;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.IBinder;
    import android.os.RemoteException;
    import android.util.Log;
    
    public class RemoteService extends Service {
    
    	private MyBilder mBilder;
    	//private final static int GRAY_SERVICE_ID = 1002;
    
    	@Override
    	public IBinder onBind(Intent intent) {
    		if (mBilder == null)
    			mBilder = new MyBilder();
    		return mBilder;
    	}
    
    	@Override
    	public void onStart(Intent intent, int startId) {
    		super.onStart(intent, startId);
    
    	}
    
    	@Override
    	public int onStartCommand(Intent intent, int flags, int startId) {
    		// 在RemoteService运行后,我们对LocalService进行绑定。 把优先级提升为前台优先级
    		this.bindService(new Intent(RemoteService.this, LocalService.class),
    				connection, Context.BIND_ABOVE_CLIENT);
    
    		Notification notification = new Notification(R.drawable.ic_launcher,
    				"安全服务启动中", System.currentTimeMillis());
    		PendingIntent pendingIntent = PendingIntent.getService(this, 0, intent,
    				0);
    		notification.setLatestEventInfo(this, "安全服务", "安全服务...", pendingIntent);
    		startForeground(startId, notification);
    		return START_STICKY;
    	}
    
    	private class MyBilder extends GuardAidl.Stub {
    
    		@Override
    		public void doSomething() throws RemoteException {
    			Log.i("TAG", "绑定成功!");
    		}
    
    	}
    
    	private ServiceConnection connection = new ServiceConnection() {
    
    		/**
    		 * 在终止后调用,我们在杀死服务的时候就会引起意外终止,就会调用onServiceDisconnected
    		 * 则我们就得里面启动被杀死的服务,然后进行绑定
    		 */
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    			Log.i("TAG", "LocalService被杀死了");
    			Intent remoteService = new Intent(RemoteService.this,
    					LocalService.class);
    			RemoteService.this.startService(remoteService);
    			RemoteService.this.bindService(new Intent(RemoteService.this,
    					LocalService.class), connection, Context.BIND_ABOVE_CLIENT);
    		}
    
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    			Log.i("TAG", "LocalService链接成功!");
    			try {
    				if (mBilder != null)
    					mBilder.doSomething();
    			} catch (RemoteException e) {
    				e.printStackTrace();
    			}
    		}
    	};
    
    }
    

    完成


    展开全文
  • 保活Service我们需要做什么: 1.在应用被关闭后保活(最难) 2.在内用占用过大,系统自动释放内存时保活(优先杀死占用较高的Service) 3.重启手机后自动开启Service 4.手机息屏后不被释放内存 5.手动清理内存...

    保活Service我们需要做什么:

    1.在应用被关闭后保活(最难)

    2.在内用占用过大,系统自动释放内存时保活(优先杀死占用较高的Service)

    3.重启手机后自动开启Service

    4.手机息屏后不被释放内存

    5.手动清理内存时保活

    首先介绍一下Service的等级:

    一、前台进程
    二、可见进程
    三、服务进程
    四、后台进程
    五、空进程  ---关闭应用后,没有清理缓存

    所以为了提高优先级我们可以使用startForeground()方法将Service设置为前台进程。

    一、在AndroidManifest中添加Service

    <service android:name=".modle.StepService"
                android:process="istep.service"  //放入新进程
                >
                <intent-filter android:priority="1000">
                    <!-- 系统启动完成后会调用-->
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                    <action android:name="android.intent.action.DATE_CHANGED"/>
                    <action android:name="android.intent.action.MEDIA_MOUNTED" />
                    <action android:name="android.intent.action.USER_PRESENT" />
                    <action android:name="android.intent.action.ACTION_TIME_TICK" />
                    <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
                </intent-filter>
    </service>
     
     
    <service android:name=".modle.GuardService"
                android:process=":GuardService">
                <intent-filter >
                    <!-- 系统启动完成后会调用-->
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                    <action android:name="android.intent.action.DATE_CHANGED"/>
                    <action android:name="android.intent.action.MEDIA_MOUNTED" />
                    <action android:name="android.intent.action.USER_PRESENT" />
                    <action android:name="android.intent.action.ACTION_TIME_TICK" />
                    <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                    <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
                </intent-filter>
            </service>

    二、双进程保护

    1.创建aidl实现跨进程通信(新建一个aidl)

    interface ProcessConnection {
        /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
        //删除不必要方法
     }

    2.创建主服务

    
    /**
     * 主进程 双进程通讯
     * Created by db on 2018/1/11.
     */
     
    public class StepService extends Service{
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return new ProcessConnection.Stub() {};
        }
     
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startForeground(1,new Notification());
            //绑定建立链接
            bindService(new Intent(this,GuardService.class),
                    mServiceConnection, Context.BIND_IMPORTANT);
            return START_STICKY;
        }
     
        private ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                //链接上
                Log.d("test","StepService:建立链接");
            }
     
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                //断开链接
                startService(new Intent(StepService.this,GuardService.class));
                //重新绑定
                bindService(new Intent(StepService.this,GuardService.class),
                        mServiceConnection, Context.BIND_IMPORTANT);
            }
        };
     
    }

    3.创建守护服务

    /**
     * 守护进程 双进程通讯
     * Created by db on 2018/1/11.
     */
     
    public class GuardService extends Service{
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return new ProcessConnection.Stub() {};
        }
     
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startForeground(1,new Notification());
            //绑定建立链接
            bindService(new Intent(this,StepService.class),
                    mServiceConnection, Context.BIND_IMPORTANT);
            return START_STICKY;
        }
     
        private ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                //链接上
                Log.d("test","GuardService:建立链接");
            }
     
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                //断开链接
                startService(new Intent(GuardService.this,StepService.class));
                //重新绑定
                bindService(new Intent(GuardService.this,StepService.class),
                        mServiceConnection, Context.BIND_IMPORTANT);
            }
        };
     
    }

    返回参数含义:

    START_STICKY:在Service被关闭后,重新开启Service
    START_NOT_STICKY:服务被异常杀掉后,系统将会被设置为started状态,系统不会重启该服务,直到startService(Intent intent)方法再次被调用。
    START_REDELIVER_INTENT:重传Intent,使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
    START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

    三、使用JobService来实现应用退出后重启Service

    1、在AndroidManifest中添加Service和权限

    <!--JobService权限-->
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <receiver android:name=".modle.BootCompleteReceiver">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                </intent-filter>
    </receiver>

    2、JobService代码

    /**
     * 用于判断Service是否被杀死
     * Created by db on 2018/1/11.
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)//5.0以后可用
    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(2000);
            JobScheduler mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
            mJobScheduler.schedule(mJobBulider.build());
            return START_STICKY;
        }
     
        @Override
        public boolean onStartJob(JobParameters jobParameters) {
            //开启定时任务 定时轮寻 判断应用Service是否被杀死
            //如果被杀死则重启Service
            boolean messageServiceAlive = serviceAlive(StepService.class.getName());
            if(!messageServiceAlive){
                startService(new Intent(this,StepService.class));
            }
     
            return false;
        }
     
        @Override
        public boolean onStopJob(JobParameters jobParameters) {
     
            return false;
        }
     
        /**
         * 判断某个服务是否正在运行的方法
         * @param serviceName
         *            是包名+服务的类名(例如:net.loonggg.testbackstage.TestService)
         * @return true代表正在运行,false代表服务没有正在运行
         */
        private boolean serviceAlive(String serviceName) {
            boolean isWork = false;
            ActivityManager myAM = (ActivityManager)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;
        }
    }

    四、保证Service在开机后自动启动

    1)注册广播

    <receiver android:name=".modle.mReceiver">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                </intent-filter>
      </receiver>

    2)广播代码

    /**
     * 开机完成广播
     */
     
    public class mReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent){
            Intent mIntent = new Intent(context,StepService.class);
            context.startService(mIntent);
        }
    }

    五、保证息屏后不被释放资源杀死(WakeLock的使用)

    (1)添加权限

    <uses-permission android:name="android.permission.WAKE_LOCK" />

    (2)在创建Service以后调用方法

    /**
         * 同步方法   得到休眠锁
         * @param context
         * @return
         */
        synchronized private void getLock(Context context){
            if(mWakeLock==null){
                PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
                mWakeLock=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,StepService.class.getName());
                mWakeLock.setReferenceCounted(true);
                Calendar c=Calendar.getInstance();
                c.setTimeInMillis((System.currentTimeMillis()));
                int hour =c.get(Calendar.HOUR_OF_DAY);
                if(hour>=23||hour<=6){
                    mWakeLock.acquire(5000);
                }else{
                    mWakeLock.acquire(300000);
                }
            }
            Log.v(TAG,"get lock");
        }

    (3)在onDestroy()方法中调用释放锁的方法(避免占用内存)

    synchronized private void releaseLock()
        {
            if(mWakeLock!=null){
                if(mWakeLock.isHeld()) {
                    mWakeLock.release();
                    Log.v(TAG,"release lock");
                }
     
                mWakeLock=null;
            }
        }

    PARTIAL_WAKE_LOCK    保持CPU运转,屏幕和键盘灯有可能是关闭的。
    SCREEN_DIM_WAKE_LOCK    保持CPU运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯。
    SCREEN_BRIGHT_WAKE_LOCK    保持CPU运转,保持屏幕高亮显示,允许关闭键盘灯。
    FULL_WAKE_LOCK    保持CPU运转,保持屏幕高亮显示,键盘灯也保持亮度。
    ACQUIRE_CAUSES_WAKEUP    不会唤醒设备,强制屏幕马上高亮显示,键盘灯开启。有一个例外,如果有notification弹出的话,会唤醒设备。
    ON_AFTER_RELEASE    Wake Lock被释放后,维持屏幕亮度一小段时间,减少Wake Lock循环时的闪烁情况。

    六、启动所有Service(在Activity中)

    /**
         * 开启所有Service
         */
        private void startAllServices()
        {
            startService(new Intent(this, StepService.class));
            startService(new Intent(this, GuardService.class));
            if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.LOLLIPOP) {
                Log.d(TAG, "startAllServices: ");
                //版本必须大于5.0
                startService(new Intent(this, JobWakeUpService.class));
            }
        }

    注意:该方法不能保证在所有机型上有效,而且除非在必要时,否则不建议写这样的流氓软件。特别是谷歌在android7.0以后对管理加强,想要保活Service其实已经变得不太可能了,谷歌这样做无疑是为了减少流氓软件的数量,这样做也是可取的。


    展开全文
  • Android Service保活

    2021-02-02 10:59:10
    保活Service我们需要做什么: 1.在应用被关闭后保活 2.在内用占用过大,系统自动释放内存时保活(优先杀死占用较高的Service) 3.重启手机后自动开启Service 4.手机息屏后不被释放内存 5.手动清理内存时保活 ...

    保活Service我们需要做什么:

    1.在应用被关闭后保活

    2.在内用占用过大,系统自动释放内存时保活(优先杀死占用较高的Service)

    3.重启手机后自动开启Service

    4.手机息屏后不被释放内存

    5.手动清理内存时保活

    Android进程的生命周期

    与大家比较熟悉的Activity生命周期相比,Android进程的生命周期实质更为简单,越核心的东西越简单嘛,Android将一个进程分为五种不同的状态:

    一、前台进程 Foreground process
    二、可见进程 Visible process
    三、服务进程 Service process
    四、后台进程 Background process
    五、空进程 Empty process

    后台进程常驻的实现

    进程提权

    adj值越小的进程越不容易被杀死,相对普通进程来说能让adj去到0显然是最完美的,可是我们如何才能让一个完全没有可见元素的后台进程拥有前台进程的状态呢?Android给了Service这样一个功能:startForeground,它的作用就像其名字一样,将我们的Service置为前台,不过你需要发送一个Notification:

    public class DaemonService extends Service {
        @Override
        public void onCreate() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                Notification.Builder builder = new Notification.Builder(this);
                builder.setSmallIcon(R.mipmap.ic_launcher);
                startForeground(250, builder.build());
            } else {
                startForeground(250, new Notification());
            }
        }
    }

    双进程保护

    1.创建aidl实现跨进程通信(新建一个aidl)

    interface ProcessConnection {
        /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
        //删除不必要方法
     }

    2.创建主服务

    /**
     * 主进程 双进程通讯
     * Created by db on 2018/1/11.
     */
     
    public class StepService extends Service{
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return new ProcessConnection.Stub() {};
        }
     
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startForeground(1,new Notification());
            //绑定建立链接
            bindService(new Intent(this,GuardService.class),
                    mServiceConnection, Context.BIND_IMPORTANT);
            return START_STICKY;
        }
     
        private ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                //链接上
                Log.d("test","StepService:建立链接");
            }
     
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                //断开链接
                startService(new Intent(StepService.this,GuardService.class));
                //重新绑定
                bindService(new Intent(StepService.this,GuardService.class),
                        mServiceConnection, Context.BIND_IMPORTANT);
            }
        };
     
    }

    3.创建守护服务

     /**
     * 守护进程 双进程通讯
     * Created by db on 2018/1/11.
     */
     
    public class GuardService extends Service{
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return new ProcessConnection.Stub() {};
        }
     
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startForeground(1,new Notification());
            //绑定建立链接
            bindService(new Intent(this,StepService.class),
                    mServiceConnection, Context.BIND_IMPORTANT);
            return START_STICKY;
        }
     
        private ServiceConnection mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                //链接上
                Log.d("test","GuardService:建立链接");
            }
     
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                //断开链接
                startService(new Intent(GuardService.this,StepService.class));
                //重新绑定
                bindService(new Intent(GuardService.this,StepService.class),
                        mServiceConnection, Context.BIND_IMPORTANT);
            }
        };
     
    }
     

    返回参数含义:

    • START_STICKY:在Service被关闭后,重新开启Service
    • START_NOT_STICKY:服务被异常杀掉后,系统将会被设置为started状态,系统不会重启该服务,直到startService(Intent intent)方法再次被调用。
    • START_REDELIVER_INTENT:重传Intent,使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
    • START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

    使用JobService来实现应用退出后重启Service

    什么是JobService

    JobService也是一个service,和普通的service不同的是,JobService是一个任务回调类,通过JobScheduler设置任务给系统,系统来调用JobService中的方法,具体处理什么任务需要我们自己在JobService中的回调方法中实现。那么关于任务的管理和进程的维护、调度当然是由系统来统一管理。

    Google从Android SDK 21之后添加了JobScheduler来执行一些满足特定条件但不紧急的后台任务,我们可以利用JobScheduler来执行这些特殊的后台任务时来减少电量的消耗。

    使用JobService来实现APP进程防杀。 
    1.首先声明权限

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <service
                android:name=".MyJobDaemonService"
                android:enabled="true"
                android:exported="true"
                android:permission="android.permission.BIND_JOB_SERVICE" />

    2.自定义一个Service类,继承自JobService

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public class MyJobDaemonService extends JobService {
        private int kJobId = 0;
     
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.i("MyJobDaemonService", "jobService启动");
            scheduleJob(getJobInfo());
            return START_NOT_STICKY;
        }
     
        @Override
        public boolean onStartJob(JobParameters params) {
            Log.i("MyJobDaemonService", "执行了onStartJob方法");
            boolean isLocalServiceWork = isServiceWork(this, "com.marswin89.marsdaemon.demo.Service1");
            boolean isRemoteServiceWork = isServiceWork(this, "com.marswin89.marsdaemon.demo.Service2");
            if(!isLocalServiceWork||
                    !isRemoteServiceWork){
                this.startService(new Intent(this,Service1.class));
    //            this.startService(new Intent(this,Service2.class));
    //            Toast.makeText(this, "进程启动", Toast.LENGTH_SHORT).show();
                Log.i("onStartJob", "启动service1");
            }
            return true;
        }
     
        @Override
        public boolean onStopJob(JobParameters params) {
            Log.i("MyJobDaemonService", "执行了onStopJob方法");
            scheduleJob(getJobInfo());
            return true;
        }
     
        //将任务作业发送到作业调度中去
        public void scheduleJob(JobInfo t) {
            Log.i("MyJobDaemonService", "调度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, MyJobDaemonService.class));
            builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_NONE);
            builder.setPersisted(true);
            builder.setRequiresCharging(false);
            builder.setRequiresDeviceIdle(false);
            //间隔1000毫秒
            builder.setPeriodic(1000);
            return builder.build();
        }
     
        // 判断服务是否正在运行
        public boolean isServiceWork(Context mContext, String serviceName) {
            boolean isWork = false;
            ActivityManager myAM = (ActivityManager) mContext
                    .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;
        }
     
    }

    保证Service在开机后自动启动

    (1)注册广播

      <receiver android:name=".modle.mReceiver">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED"/>
                </intent-filter>
      </receiver>
    /**
     * 开机完成广播
     */
     
    public class mReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent){
            Intent mIntent = new Intent(context,StepService.class);
            context.startService(mIntent);
        }
    }

    保证息屏后不被释放资源杀死(WakeLock的使用)

    (1)添加权限

        <uses-permission android:name="android.permission.WAKE_LOCK" />

    需求:要在后台跑一个Service执行轮询,屏幕熄灭或锁屏后,仍然需要保持Service一直处于轮询状态。

     应用程序中如果要在待机前保存数据状态的话,要保证此过程中不会进入待机。可以在 onResume() 或者 onStart() 中申请 wakelock 锁,即调用getLock()方法。

    在 onPause() 或者 onDistroy() 中处理应用待机后再释放掉 wakelock 锁,此时调用releaseLock()方法

       /**
         * 同步方法   得到休眠锁
         * @param context
         * @return
         */
        synchronized private void getLock(Context context){
            if(mWakeLock==null){
                PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
                mWakeLock=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,StepService.class.getName());
                mWakeLock.setReferenceCounted(true);
                Calendar c=Calendar.getInstance();
                c.setTimeInMillis((System.currentTimeMillis()));
                int hour =c.get(Calendar.HOUR_OF_DAY);
                if(hour>=23||hour<=6){
                    mWakeLock.acquire(5000);
                }else{
                    mWakeLock.acquire(300000);
                }
            }
            Log.v(TAG,"get lock");
        }
    synchronized private void releaseLock()
        {
            if(mWakeLock!=null){
                if(mWakeLock.isHeld()) {
                    mWakeLock.release();
                    Log.v(TAG,"release lock");
                }
     
                mWakeLock=null;
            }
        }

     

     

    展开全文
  • Android之Service保活

    千次阅读 2020-01-20 14:26:40
    临近年关,这一年的...要求很简单:定位、地图划线,然后就是后台服务的保活操作了。 今天,在此记录GitHub上好用的轮子:DaemonLibrary。 集成方式: Step 1. Add the JitPack repository to your build file...
  • 它是利用系统的漏洞来启动一个前台的Service进程,与普通的启动方式区别在于,它...其实市面上很多app都用着这种灰色保活的手段,什么?你不信?反正我是信了,demo在此,欢迎指正,很少写博客,就这样吧~~~~~~~忙去了
  • 为什么要保活?由于业务需求,我们希望自己的APP永远有一个后台程序在运行,时刻保持着与服务器通信,当APP退出或者被杀掉时,仍然能被唤醒,接受通知等,...故而为了能够保证service不被杀死,提出包进程保活机制。
  • 写在前头保活Service我们需要做什么:1.在应用被关闭后保活(最难)2.在内用占用过大,系统自动释放内存时保活(优先杀死占用较高的Service)3.重启手机后自动开启Service4.手机息屏后不被释放内存5.手动清理内存时保活...
  • Android Service保活最佳实践

    千次阅读 2019-04-28 17:38:08
    最近的项目因为服务在后台被杀...进程守护 这个方法貌似现在不行了。 START_STICKY 一开始就有,没什么用。 使用前台进程 可以实现保活,但是通知栏会有xxx正在运行的通知,很难受。网上说的使用两个前台进程...
  • android:service保活

    千次阅读 2018-08-02 14:20:44
    1、修改Service的onStartCommand 方法返回值 当服务被异常终止,是否能重启服务? 一般的做法是修改返回值,返回START_ STICKY。 onStartCommand()返回一个整型值,用来描述系统在杀掉服务后是否要继续启动服务,...
  • JobSchedule与Service保活

    千次阅读 2018-12-02 11:35:11
    Android Service保活主要在两个层面 提高service优先级,降低service被杀死的概率。 在service被杀死后进行拉活。。 3.1 灰色保活方案简介 startForeground(ID, new Notification()),可以将Service...
  • 1、ProcessService.aidlpackage com.freeman.inter;interface ProcessService{String ...}2、本地服务LocalServicepublic class LocalService extends Service {public static final String TAG = "Info";pr...
  • 官方文档说明: https://lbs.amap.com/dev/demo/service-location#Android 核心难点 首先在本地服务中启动连续定位功能,通过设置一个...getApplicationContext().startService(new Intent(this, LocationService.c.
  • Android 7.0 Service保活总结

    万次阅读 2017-11-06 15:36:41
    我先说一个最近研究得出来的结论,在7.0这个版本,包括三星和国内的这些原生rom,如果不通过用户或厂家设置,至少service是绝对没有任何办法保活的,绝对,除非你还能找到未知的BUG。虽然我也很头疼,但我真的很赞同...
  • 最近开发的时候,测试小伙伴经常来找我,“为什么咱家程序放到后台...对于进程保活,其实吧,现在对于MIUI、EMUI等等许多高度定制的系统并没有100%的保活方案,该死还是死掉,但是做了一定的操作,还是可以适当的提...
  • Android Service保活攻防

    2018-09-21 14:31:52
    一、为什么要保活保活的源头是由于我们希望自己服务或者进程能够一直在后台运行,但是总有各种各样的原因导致我们的希望破灭,主要原因有如下几种:1、Android系统回收;2、手机厂商定制管理系统,如电源管理、...
  • 一、 进程守护保活原理、 二、 进程守护保活完整源码、 1、AIDL 接口、 2、本地前台服务 Service、 3、远程前台服务 Service、 4、清单配置、 5、启动两个服务、 5、执行效果、 三、 源码资源
  • 首先要声明,进程保活,不是为了解决被杀之后复活的问题。因为在新版本的安卓上,这个办法已经不灵了(也许有人有更好的办法?)。这里介绍这个进程保活,是为在电视盒子上的应用。如果进程死了,有的系统会自动...
  • 1、修改Service的onStartCommand 方法返回值 当服务被异常终止,是否能重启服务? 一般的做法是修改返回值,返回START_ STICKY。 onStartCommand()返回一个整型值,用来描述系统在杀掉服务后是否要继续启动服务,...
  • Android进程保活·设置前台Service,提升App进程优先级 Android进程 此文章代码Github上有提交: 首先你要知道Android中的进程以及它的优先级,下面来说明它进程 前台进程 (Foreground process) 可见进程 ...
  • 进程保活,service保活

    2018-12-28 12:33:17
    一、onStartCommand方法,返回START_STICKY ...不久后service就会再次尝试重新创建,因为保留在开始状态,在创建 service后将保证调用onstartCommand。如果没有传递任何开始命令给service,那...
  • IPC - Service保活

    2019-12-11 12:08:04
    1.Service为什么会被杀死? 1>手机内存不足时,Service有可能被杀死; 2>360,手机管家等优化内存时,Service可能被杀死; 2.进程的优先级 1.前台进程 用户当前操作所必需的进程。如果一个进程满足以下...
  • 进程保活思路学习总结

    千次阅读 2017-09-15 14:45:52
    服务端Service中返回IBinder对象为 AIDL文件生成Java文件后的内部类Sub 客户端bindService,在ServiceConnection中的连接成功方法中会返回一个IBinder对象,通过AIDL对应的java类的asInterface方法可以将IBinder...
  • 它是利用系统的漏洞来启动一个前台的Service进程,与普通的启动方式区别在于,它不会在系统通知栏处出现一个Notification,看起来就如同运行着一个后台Service进程一样。这样做带来的好处就是,用户无法察觉到你运行...
  • android 两个service实现相互保活

    千次阅读 2018-12-13 09:49:32
    1,实现原理,2个service不在同一个进程中,一个A进程,一个B进程,A和B通过广播机制来通讯,当A进程被杀死的时候,发送广播给B进程,B进程收到广播后再次启动A服务,相反的B进程被杀死,由A来重新启动。 2,A 服务...
  • 进程的保活,在很多资讯类的App和即时通讯App的用处很大,奈何谷歌的推送服务在国内是被阉割了!据说是在8.0(奥利奥)相关政府机构已经将开放这项功能提上了日程,嗯,没错8.0,预计再过三五年就可以像苹果那样...
  • Android进程保活·设置前台Service,提升App进程优先级 Android进程 首先你要知道Android中的进程以及它的优先级,下面来说明它进程 前台进程 (Foreground process) 可见进程 (Visible process) 服务进程 ...
  • 该文写的主要目的在于巩固下对app保活的使用以及理解,主要用于自己回头查看,不喜勿喷,可以直接看上面链接的内容,以上链接同样附有完整demo,亲测有效。 一、核心思想归纳 App保活主要通过两个方面:1.降低omm_...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,750
精华内容 700
关键字:

双service保活