Andrioid进程保护

Posted boy_nihao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Andrioid进程保护相关的知识,希望对你有一定的参考价值。

转载请注明出处:z_zhaojun的博客       原文地址


这篇博文主要是关于进程保活的应用,通过对网上各种进程保活方式的学习,自己理解后做汇总、优化、简单封装。

进程保活,主要就为了加强你写的app在手机上的生存能力,降低被手机干掉的几率。当然,如果想要完全保证app不被杀死,那是不可能的(因为就是你再厉害,也厉害不过手机厂商),所以只能是尽量提高app的存活几率。下面将通过‘AIDL +JobService(JobScheduler)’来实现这个目标。


第一步、通过AIDL来实现双进程守护,达到初步加强app存活能力的目的
          显示在最开始你必须先新建一个AIDL服务(具体玩法自行百度),先上相关代码:

LocalService.java

//LocalService是一个运行在当前app进程的一个服务,在这里你可以实现你想要一直放在后台执行的功能。实现了ServiceConnection接口,用于监听兄弟服务RemoteService(具体代码请往下看)状态,在监听到RemoteService被杀死后,重新开启兄弟服务RemoteSerivce
class LocalService extends Service implements ServiceConnection 

    private static final String TAG = "LocalService";

    private LocalServiceBinder localBinder;

    private Notification notification;

    @Override
    public void onCreate() 
        Log.d(TAG, "onCreate");
        if (null == localBinder) 
            //与RemoteService绑定时需要
            localBinder = new LocalServiceBinder();
        
        super.onCreate();
    

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
        Log.d(TAG, "onStartCommand");
        startJob();
        //提高服务优先级,降低被杀的概率
        startForeground(startId, getNotification());
        //与兄弟服务RemoteService绑定,这有这样才能监听到RemoteService的状态
        bindService(new Intent(LocalService.this, RemoteService.class),
                this, Context.BIND_IMPORTANT);
        return START_STICKY;
    

    //在这里开始你想要实现的功能,已经做了简单封装,博文末尾会有操作方式
    private boolean startJob() 
        return AliveServiceManagerImpl.getInstance().startJob();
    

    @NonNull
    private Notification getNotification() 
        if (null == notification) 
            Notification.Builder builder = new Notification.Builder(this);
            builder.setDefaults(NotificationCompat.FLAG_AUTO_CANCEL);
            builder.setContentTitle(TAG);
            builder.setSmallIcon(R.drawable.logonews);
            builder.setSubText(TAG);
            builder.setContentText(TAG);
            builder.setWhen(System.currentTimeMillis());
            /*PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
            builder.setContentIntent(pi);*/
            notification = builder.build();
        
        return notification;
    

    @Override
    public IBinder onBind(Intent intent) 
        Log.d(TAG, "onBind");
        return localBinder;
    

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) 
        Log.d(TAG, "onServiceConnected");
    

    //当兄弟服务RemoteService被杀死时,会触发onServiceDisconnected方法,在这里重新开启RemoteService,并绑定
    @Override
    public void onServiceDisconnected(ComponentName name) 
        Log.d(TAG, "onServiceDisconnected");
        startService(new Intent(this, RemoteService.class));
        bindService(new Intent(this, RemoteService.class), this, Context.BIND_IMPORTANT);
    

    //AIDL服务
    private class LocalServiceBinder extends IServiceAidlInterface.Stub 

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException 
            Log.d(TAG, "basicTypes");
        
    

RemoteService .java

//RemoteService 是一个运行在与当前app进程相独立的进程中的服务,并实现了ServiceConnection接口,用于监听兄弟服务LocalService的状态,在监听到LocalService被杀死后,重新开启兄弟服务LocalService
class RemoteService extends Service implements ServiceConnection 

    private static final String TAG = "RemoteService";

    private RemoteServiceBinder remoteBinder;

    private Notification notification;

    @Override
    public void onCreate() 
        Log.d(TAG, "onCreate");
        if (null == remoteBinder) 
            remoteBinder = new RemoteServiceBinder();
        
        super.onCreate();
    

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
        Log.d(TAG, "onStartCommand");
        //提高服务优先级,降低被杀的概率
        startForeground(startId, getNotification());
        //与兄弟服务LocalService绑定,这有这样才能监听到LocalService的状态
        bindService(new Intent(this, LocalService.class), this, Context.BIND_IMPORTANT);
        return START_STICKY;
    

    @NonNull
    private Notification getNotification() 
        if (null == notification) 
            Notification.Builder builder = new Notification.Builder(this);
            builder.setDefaults(NotificationCompat.FLAG_AUTO_CANCEL);
            builder.setContentTitle(TAG);
            builder.setSmallIcon(R.mipmap.ic_launcher);
            builder.setSubText(TAG);
            builder.setContentText(TAG);
            builder.setWhen(System.currentTimeMillis());
            /*PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
            builder.setContentIntent(pi);*/
            notification = builder.build();
        
        return notification;
    

    @Override
    public IBinder onBind(Intent intent) 
        Log.d(TAG, "onBind");
        return remoteBinder;
    

    //当兄弟服务LocalService被杀死时,会触发onServiceDisconnected方法,在这里重新开启LocalService,并绑定
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) 
        Log.d(TAG, "onServiceConnected");
    

    @Override
    public void onServiceDisconnected(ComponentName name) 
        Log.d(TAG, "onServiceDisconnected");
        startService(new Intent(this, LocalService.class));
        bindService(new Intent(this, LocalService.class), this, Context.BIND_IMPORTANT);
    

    private class RemoteServiceBinder extends IServiceAidlInterface.Stub 

        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException 
            Log.d(TAG, "basicTypes");
        
    

LocalService、RemoteService在androidManifest.xml中的添加方式:

<service
            android:name=".aliveservice.LocalService"
            android:enabled="true"
            android:exported="true">
        </service>
        <service
            android:name=".aliveservice.RemoteService"
            android:process=":remote"//用于开启新的进程:包名+“:remoteandroid:enabled="true"
            android:exported="true">//为true表示对其它进程可见
        </service>

第二步、结合JobService使用
          JobService+Jobschedule有点类似手机系统闹钟(alertmanager),是android5.0之后提供的机制,可以让系统在某些特定环境下或固定时间间隔里,异步执行一些作业,其主要目的就是为了优化电池。当然,在这里主要是为了保护兄弟服务LocalService+RemoteService。

具体代码:

LocalJobService.java

<service
            android:name=".aliveservice.LocalJobService"
            android:permission="android.permission.BIND_JOB_SERVICE"
            android:enabled="true"
            android:exported="true">
        </service>
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
class LocalJobService extends JobService 
    private static final String TAG = "LocalJobService";
    private static final String KEY_LOCAL_SERVICE_NAME = LocalService.class.getName();
    private static final String KEY_REMOTE_SERVICE_NAME = RemoteService.class.getName();

    private JobInfo jobInfo;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
        Log.i(TAG, "onStartCommand");
        scheduleJob(getJobInfo());
        return START_NOT_STICKY;
    

    //一旦开启当前服务,系统会定时调用onStartJob方法,在其中判断兄弟服务LocalService+RemoteService的存活情况,如果被杀死则重新启动相应服务
    @Override
    public boolean onStartJob(JobParameters params) 
        Log.i(TAG, "onStartJob");
        boolean isLocalServiceWork = isServiceWork(this, KEY_LOCAL_SERVICE_NAME);
        boolean isRemoteServiceWork = isServiceWork(this, KEY_REMOTE_SERVICE_NAME);
        if (!isLocalServiceWork) 
            this.startService(new Intent(this, LocalService.class));
        
        if (!isRemoteServiceWork) 
            this.startService(new Intent(this, RemoteService.class));
        
        return true;
    

    @Override
    public boolean onStopJob(JobParameters params) 
        Log.i(TAG, "onStopJob");
        scheduleJob(getJobInfo());
        return true;
    

    /**
     * 将任务作业发送到作业调度中去
     */
    public void scheduleJob(JobInfo info) 
        Log.i(TAG, "scheduleJob");
        JobScheduler js = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
        js.schedule(info);
    

    public JobInfo getJobInfo() 
        Log.i(TAG, "getJobInfo");
        if (null == jobInfo) 
            JobInfo.Builder builder = new JobInfo.Builder(0, new ComponentName(this, LocalJobService.class));
            builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
            builder.setPersisted(true);
            builder.setRequiresCharging(false);
            builder.setRequiresDeviceIdle(false);
            //间隔100毫秒
            builder.setPeriodic(100);
            jobInfo = builder.build();
        
        return jobInfo;
    

    /**
     * 判断服务是否正在运行
     */
    public boolean isServiceWork(Context mContext, String serviceName) 
        if (TextUtils.isEmpty(serviceName)) 
            return false;
        

        boolean isWorking = false;
        ActivityManager manager = (ActivityManager) mContext
                .getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> list = manager.getRunningServices(100);
        for (ActivityManager.RunningServiceInfo info : list) 
            String name = info.service.getClassName();
            if (serviceName.equals(name)) 
                isWorking = true;
                break;
            
        
        return isWorking;
    

第三步、简单封装
                     具体实现请看代码:
AliveServiceManagerImpl.java

/**
 * package: com.zzj.chris.processalivedemo.aliveservice
 * <p>
 * description: 保活service管理
 * <p>
 * Created by chris on 2017/8/7.
 */

public class AliveServiceManagerImpl implements AliveServiceManager 
    private static final Byte[] LOCK = new Byte[0];

    private static AliveServiceManager mInstance;

    private List<JobSchedule> mJobObservers;

    private AliveServiceManagerImpl() 

    //单例
    public static AliveServiceManager getInstance() 
        if (null == mInstance)
            synchronized (LOCK) 
                if (null == mInstance)
                    mInstance = new AliveServiceManagerImpl();
                
            
        
        return mInstance;
    

    //在这里开启进程保活功能
    @Override
    public void start(Context context) //app.getContext
        context.startService(new Intent(context, LocalService.class));
        context.startService(new Intent(context, RemoteService.class));
        if (Build.VERSION.SDK_INT >= 21) 
            context.startService(new Intent(context, LocalJobService.class));
        
    

    @Override
    public void stop(Context context) 

    

    @Override
    public void destroy() 
        if (null != mJobObservers) 
            mJobObservers.clear();
            mJobObservers = null;
        
        mInstance = null;
    

    //开始执行你在后台想要实现的功能
    @Override
    public boolean startJob() 
        boolean isWorking = false;
        getObservers();
        for (JobSchedule schedule : mJobObservers) 
            if (!schedule.isWorking()) 
                schedule.start();
                isWorking = true;
            
        
        return isWorking;
    

    private void getObservers() 
        if (null == mJobObservers) 
            mJobObservers = new ArrayList<>();
        
        if (mJobObservers.size() <= 0) 
            //这里需要手动添加
            mJobObservers.add(NotificationHelper.getInstance());
            mJobObservers.add(*******);
            ......
        
    

使用实例:
新建NotificationHelper类实现AliveServiceManager.JobSchedule接口(具体请看demo源码,末尾附下载地址):

NotificationHelper。java

public class NotificationHelper implements AliveServiceManager.JobSchedule 
    private static final String TAG = "NotificationHelper";

    private static NotificationHelper mHelper;

    private boolean isWork;

    private NotificationHelper() 

    public static NotificationHelper getInstance() 
        if (null == mHelper) 
            mHelper = new NotificationHelper();
        
        return mHelper;
    

    @Override
    public void start() //在这执行需要实现的工作
        if (!isWork) 
//            startTimer();
            isWork = true;
        
    

    @Override
    public void stop() 
//        stopTimer();
        isWork = false;
    

    @Override
    public boolean isWorking() 
        return isWork;
    

最后就是具体用法:

AliveServiceManagerImpl.getInstance().start(this);

下载地址:
      CSDN
      GitHub

以上是关于Andrioid进程保护的主要内容,如果未能解决你的问题,请参考以下文章

怎么才能保护自己在互联网中的安全呢

Andrioid 性能优化基础

Andrioid FileProvider在Xamarin.Forms中的使用

求exe程序进程自我保护功能不被系统自带的任务管理器结束掉

java-并发-保护代码块

Linux进程5——实模式和保护模式