精华内容
下载资源
问答
  • 双进程守护

    2016-09-06 10:57:11
    简单的双进程守护,使用了android 5.0的新特性jobservice对app有效的保活。缺点:5.0以上手机难以做到完全保活。
  • 博文:http://blog.csdn.net/andrexpert/article/details/53485360 双进程守护Demo
  • Android双进程守护

    2016-06-06 14:39:34
    通过NDK实现双进程守护
  • android双进程守护,进程很难被杀死demo

    千次下载 热门讨论 2014-12-15 19:18:11
    android双进程守护,进程很难被杀死
  • 安卓双进程守护

    2016-07-10 18:20:25
    实现安卓的双进程守护,该功能只限学术研究,如果应用于自己的程序,请三思而后行!
  • Android 双进程守护

    2016-06-24 11:05:12
    1.实现双进程守护,2,系统清理还是会被杀死,想QQ、微信、他们这些已经被厂家加入白名单了,除非你也去向厂家申明添加白名单(你要有本事哦),3第三方清理软件,像350安全卫士这样的清理软件表面上杀死了,但是...
  • 主要介绍了Android 双进程守护的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • Android双进程守护Dnprocessmul.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。
  • 进程保活之双进程守护

    千次阅读 2017-05-21 11:29:41
    双进程守护场景:home键,系统应用管理,直接杀死进程,进程仍然处于运行状态; 适用手机类型:50%的手机。 双进程守护原理: 进程A 进程B 删除A,同时创建B 删除B,同时创建A 前提相关知识: 1、Service分类...

    双进程守护场景:home键,系统应用管理,直接杀死进程,进程仍然处于运行状态;
    适用手机类型:50%的手机。
    双进程守护原理:
    进程A 进程B
    删除A,同时创建B
    删除B,同时创建A
    前提相关知识:
    1、Service分类:一种localService 也就是普通的Service;另一种是RemoteService,远程服务,也就是我们常说的AIDL,它是由IPC引进的一种链接两个进程,两个app的技术;
    2、AIDL使用模式:
    ①定义AIDL接口;
    ②为远程服务实现对应的stub;
    ③将服务暴露给客户程序;
    代码实现:
    一、创建IServiceAidlInterface.aidl

    // Declare any non-default types here with import statements
    
    interface IServiceAidlInterface {
        /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
        void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
                double aDouble, String aString);
    }

    二、创建本地LocalService

    public class LocalService extends Service {
        private static String TAG = "LocalService";
        LocalServiceBinder localBinder;
        LocalServiceConnection localCnn;
        private int count = 0;
    
    
        @Override
        public void onCreate() {
            super.onCreate();
            if (localBinder == null) {
                localBinder = new LocalServiceBinder();
            }
            localCnn = new LocalServiceConnection();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startTime();
            Notification.Builder builder = new Notification.Builder(this);
            builder.setDefaults(Notification.DEFAULT_SOUND);
            builder.setContentTitle("Xiaoke Wang");
            builder.setSmallIcon(R.mipmap.ic_launcher);
            builder.setContentInfo("info");
            builder.setWhen(System.currentTimeMillis());
            PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 0);
            builder.setContentIntent(pi);
            //将serviceprocess提高到foreground process 优先级
            startForeground(startId, builder.build());
            //确保后台运行
            return START_STICKY;
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
    //        throw new UnsupportedOperationException("Not yet implemented");
            return localBinder;
        }
    
        /**
         * 暴露外部接口
         */
        class LocalServiceConnection implements ServiceConnection {
    
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    
            }
    
            /**
             * 当服务断开连接时调用,本地服务断开时创建另一个服务
             * @param componentName
             */
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                Log.d(TAG, "onServiceDisconnected");
                LocalService.this.startService(new Intent(LocalService.this, RemoteService.class));
                LocalService.this.bindService(new Intent(LocalService.this, RemoteService.class), localCnn, Context.BIND_IMPORTANT);
            }
        }
    
        /**
         * 为远程服务实现对应的stub
         */
        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:

    public class RemoteService extends Service {
        private static final String TAG = "RemoteService";
        RemoteServiceBinder remoteBinder;
        RemoteServiceConnection remoteCnn;
        private int count=0;
    
    
        @Override
        public void onCreate() {
            super.onCreate();
            if (remoteBinder ==null){
                remoteBinder =new RemoteServiceBinder();
            }
            remoteCnn =new RemoteServiceConnection();
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
    //        throw new UnsupportedOperationException("Not yet implemented");
            return remoteBinder;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            startTime();
            Notification.Builder builder=new Notification.Builder(this);
            builder.setDefaults(Notification.DEFAULT_SOUND);
            builder.setContentTitle("Xiaoke Wang");
            builder.setSmallIcon(R.mipmap.ic_launcher);
            builder.setContentInfo("info");
            builder.setWhen(System.currentTimeMillis());
            PendingIntent pi=PendingIntent.getActivity(this,0,intent,0);
            builder.setContentIntent(pi);
            //将serviceprocess提高到foreground process 优先级
            startForeground(startId,builder.build());
            return START_STICKY;
        }
    
        /**
         * 暴露外部接口
         */
        class RemoteServiceConnection implements ServiceConnection {
    
            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
    
            }
    
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                Log.d(TAG,"onServiceDisconnected");
                RemoteService.this.startService(new Intent(RemoteService.this,LocalService.class));
                RemoteService.this.bindService(new Intent(RemoteService.this,LocalService.class),remoteCnn, Context.BIND_IMPORTANT);
            }
        }
    
        /**
         * 为远程服务实现对应的stub
         */
        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");
            }
        }

    四、清单文件配置:

       <service
                android:name=".LocalService"
                android:enabled="true"
                android:exported="true" />
            <service
                android:name=".RemoteService"
                android:enabled="true"
                android:exported="true"
                android:process=":remote"/>

    五、MainAct开启服务:

      startService(new Intent(this,LocalService.class));
            startService(new Intent(this,RemoteService.class));

    ok项目结束,相关源码,请留下邮箱。

    展开全文
  • 【Android 进程保活】应用进程拉活 ( 双进程守护保活 ) https://hanshuliang.blog.csdn.net/article/details/115604667 博客源码快照
  • Android杀不死的进程ForkNDK示例,双进程守护
  • Android双进程守护程序, 不会被杀死
  • 一、 双进程守护保活原理、 二、 双进程守护保活完整源码、 1、AIDL 接口、 2、本地前台服务 Service、 3、远程前台服务 Service、 4、清单配置、 5、启动两个服务、 5、执行效果、 三、 源码资源





    一、 双进程守护保活原理



    双进程守护拉活 , 使用 JobScheduler 拉活 和 系统 Service 机制拉活 两种拉活方式 , 结合起来使用 ;

    双进程机制拉活 , 比之前的 广播拉活 , 系统 Service 机制拉活 , 账户同步拉活 , JobScheduler 机制拉活 , 成功率都要高 , 可靠性比较高 , 但是也存在失败的情况 ;


    JobScheduler 原理 :

    在应用中 , 运行了一个主进程 , 除此之外 , 还运行了一个 " 本地前台进程 " , 运行该 " 本地前台进程 " 时 , 开启前台进程 , 用于提权 , 并绑定 " 远程前台进程 " ;

    " 远程前台进程 " 与 " 本地前台进程 " 实现了相同的功能 , 代码基本一致 , 这两个进程都是前台进程 , 都进行了提权 , 并且互相绑定 , 当监听到绑定的另外一个进程突然断开连接 , 则本进程再次开启前台进程提权 , 并且重新绑定对方进程 , 以达到拉活对方进程的目的 ;


    举例 : " 本地前台进程 " LocalForegroundService , " 远程前台进程 " RemoteForegroundService ;

    这两个进程之间需要绑定 , 这里就需要定义 AIDL 接口 IMyAidlInterface , 每个服务中都需要定义继承 IMyAidlInterface.Stub 的 Binder 类 , 作为进程间通信的桥梁 ; ( 这是个默认的 AIDL 接口 )

        /**
         * AIDL 远程调用接口
         * 其它进程调与该 RemoteForegroundService 服务进程通信时 , 可以通过 onBind 方法获取该 myBinder 成员
         * 通过调用该成员的 basicTypes 方法 , 可以与该进程进行数据传递
         */
        class MyBinder extends IMyAidlInterface.Stub {
            @Override
            public void basicTypes(
                    int anInt, long aLong, boolean aBoolean, float aFloat,
                    double aDouble, String aString) throws RemoteException {
                // 通信内容
            }
        }
    

    " 本地前台进程 " LocalForegroundService 在 onCreate 方法中开启前台服务 , 提权 , 参考 【Android 进程保活】提升进程优先级 ( 使用前台 Service 提高应用进程优先级 | 效果展示 | 源码资源 ) , 并且创建用于进程间通信的 Binder 对象 ;

        /**
         * 远程调用 Binder 对象
         */
        private MyBinder myBinder;
        
        @Override
        public void onCreate() {
            super.onCreate();
            // 创建 Binder 对象
            myBinder = new MyBinder();
    
            // 启动前台进程
            startService();
        }
    

    " 本地前台进程 " LocalForegroundService , 在 onBind 方法中返回 onCreate 方法中创建的 Binder 对象 ;

        @Override
        public IBinder onBind(Intent intent) {
            return myBinder;
        }
    

    " 本地前台进程 " LocalForegroundService 中 , 绑定远程进程时 , 需要使用到 ServiceConnection 类 , 在服务绑定成功时回调 onServiceConnected , 服务断开时回调 onServiceDisconnected 方法 ; 这里就在 onServiceDisconnected 方法中再次对本服务进行提权 , 并且再次绑定 " 远程前台进程 " RemoteForegroundService ;

        class Connection implements ServiceConnection {
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                // 服务绑定成功时回调
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                // 再次启动前台进程
                startService();
                // 绑定另外一个远程进程
                bindService();
            }
        }
    

    另外特别注意权限问题 , 需要在清单文件中配置 android.permission.FOREGROUND_SERVICE 权限 :

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




    二、 双进程守护保活完整源码





    1、AIDL 接口


    这里的 AIDL 不实现任何操作 , 是系统默认生成的 AIDL 接口 , 只是用于单纯的绑定两个进程 , 监听进程的连接断开 ;

    // IMyAidlInterface.aidl
    package kim.hsl.two_process_alive;
    
    // Declare any non-default types here with import statements
    
    interface IMyAidlInterface {
        /**
         * Demonstrates some basic types that you can use as parameters
         * and return values in AIDL.
         */
        void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
                double aDouble, String aString);
    }
    


    2、本地前台服务 Service


    package kim.hsl.two_process_alive;
    
    import android.app.Notification;
    import android.app.NotificationChannel;
    import android.app.NotificationManager;
    import android.app.Service;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.graphics.Color;
    import android.os.Build;
    import android.os.IBinder;
    import android.os.RemoteException;
    
    import androidx.core.app.NotificationCompat;
    
    import static androidx.core.app.NotificationCompat.PRIORITY_MIN;
    
    /**
     * 前台服务提权
     */
    public class LocalForegroundService extends Service {
    
        /**
         * 远程调用 Binder 对象
         */
        private MyBinder myBinder;
    
        /**
         * 连接对象
         */
        private Connection connection;
    
        /**
         * AIDL 远程调用接口
         * 其它进程调与该 RemoteForegroundService 服务进程通信时 , 可以通过 onBind 方法获取该 myBinder 成员
         * 通过调用该成员的 basicTypes 方法 , 可以与该进程进行数据传递
         */
        class MyBinder extends IMyAidlInterface.Stub {
            @Override
            public void basicTypes(
                    int anInt, long aLong, boolean aBoolean, float aFloat,
                    double aDouble, String aString) throws RemoteException {
                // 通信内容
            }
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return myBinder;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            // 创建 Binder 对象
            myBinder = new MyBinder();
    
            // 启动前台进程
            startService();
        }
    
        private void startService(){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
                // startForeground();
    
                // 创建通知通道
                NotificationChannel channel = new NotificationChannel("service",
                        "service", NotificationManager.IMPORTANCE_NONE);
                channel.setLightColor(Color.BLUE);
                channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
                NotificationManager service = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                // 正式创建
                service.createNotificationChannel(channel);
    
                NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "service");
                Notification notification = builder.setOngoing(true)
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setPriority(PRIORITY_MIN)
                        .setCategory(Notification.CATEGORY_SERVICE)
                        .build();
    
                // 开启前台进程 , API 26 以上无法关闭通知栏
                startForeground(10, notification);
    
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
                startForeground(10, new Notification());
                // API 18 ~ 25 以上的设备 , 启动相同 id 的前台服务 , 并关闭 , 可以关闭通知
                startService(new Intent(this, CancelNotificationService.class));
    
            } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2){
                // 将该服务转为前台服务
                // 需要设置 ID 和 通知
                // 设置 ID 为 0 , 就不显示已通知了 , 但是 oom_adj 值会变成后台进程 11
                // 设置 ID 为 1 , 会在通知栏显示该前台服务
                // 8.0 以上该用法报错
                startForeground(10, new Notification());
            }
        }
    
        /**
         * 绑定 另外一个 服务
         * LocalForegroundService 与 RemoteForegroundService 两个服务互相绑定
         */
        private void bindService(){
            // 绑定 另外一个 服务
            // LocalForegroundService 与 RemoteForegroundService 两个服务互相绑定
    
            // 创建连接对象
            connection = new Connection();
    
            // 创建本地前台进程组件意图
            Intent bindIntent = new Intent(this, RemoteForegroundService.class);
            // 绑定进程操作
            bindService(bindIntent, connection, BIND_AUTO_CREATE);
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // 绑定另外一个服务
            bindService();
            return super.onStartCommand(intent, flags, startId);
        }
    
        class Connection implements ServiceConnection {
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                // 服务绑定成功时回调
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                // 再次启动前台进程
                startService();
                // 绑定另外一个远程进程
                bindService();
            }
        }
    
        /**
         * API 18 ~ 25 以上的设备, 关闭通知到专用服务
         */
        public static class CancelNotificationService extends Service {
            public CancelNotificationService() {
            }
    
            @Override
            public void onCreate() {
                super.onCreate();
                startForeground(10, new Notification());
                stopSelf();
            }
    
            @Override
            public IBinder onBind(Intent intent) {
                return null;
            }
    
        }
    
    }
    


    3、远程前台服务 Service


    package kim.hsl.two_process_alive;
    
    import android.app.Notification;
    import android.app.NotificationChannel;
    import android.app.NotificationManager;
    import android.app.Service;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.graphics.Color;
    import android.os.Build;
    import android.os.IBinder;
    import android.os.RemoteException;
    
    import androidx.core.app.NotificationCompat;
    
    import static androidx.core.app.NotificationCompat.PRIORITY_MIN;
    
    /**
     * 前台服务提权
     */
    public class RemoteForegroundService extends Service {
    
        /**
         * 远程调用 Binder 对象
         */
        private MyBinder myBinder;
    
        /**
         * 连接对象
         */
        private Connection connection;
    
        /**
         * AIDL 远程调用接口
         * 其它进程调与该 RemoteForegroundService 服务进程通信时 , 可以通过 onBind 方法获取该 myBinder 成员
         * 通过调用该成员的 basicTypes 方法 , 可以与该进程进行数据传递
         */
        class MyBinder extends IMyAidlInterface.Stub {
            @Override
            public void basicTypes(
                    int anInt, long aLong, boolean aBoolean, float aFloat,
                    double aDouble, String aString) throws RemoteException {
                // 通信内容
            }
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return myBinder;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            // 创建 Binder 对象
            myBinder = new MyBinder();
    
            // 启动前台进程
            startService();
        }
    
        private void startService(){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
                // startForeground();
    
                // 创建通知通道
                NotificationChannel channel = new NotificationChannel("service",
                        "service", NotificationManager.IMPORTANCE_NONE);
                channel.setLightColor(Color.BLUE);
                channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
                NotificationManager service = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                // 正式创建
                service.createNotificationChannel(channel);
    
                NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "service");
                Notification notification = builder.setOngoing(true)
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setPriority(PRIORITY_MIN)
                        .setCategory(Notification.CATEGORY_SERVICE)
                        .build();
    
                // 开启前台进程 , API 26 以上无法关闭通知栏
                startForeground(10, notification);
    
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
                startForeground(10, new Notification());
                // API 18 ~ 25 以上的设备 , 启动相同 id 的前台服务 , 并关闭 , 可以关闭通知
                startService(new Intent(this, CancelNotificationService.class));
    
            } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2){
                // 将该服务转为前台服务
                // 需要设置 ID 和 通知
                // 设置 ID 为 0 , 就不显示已通知了 , 但是 oom_adj 值会变成后台进程 11
                // 设置 ID 为 1 , 会在通知栏显示该前台服务
                // 8.0 以上该用法报错
                startForeground(10, new Notification());
            }
        }
    
        /**
         * 绑定 另外一个 服务
         * LocalForegroundService 与 RemoteForegroundService 两个服务互相绑定
         */
        private void bindService(){
            // 绑定 另外一个 服务
            // LocalForegroundService 与 RemoteForegroundService 两个服务互相绑定
    
            // 创建连接对象
            connection = new Connection();
    
            // 创建本地前台进程组件意图
            Intent bindIntent = new Intent(this, LocalForegroundService.class);
            // 绑定进程操作
            bindService(bindIntent, connection, BIND_AUTO_CREATE);
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            // 绑定另外一个服务
            bindService();
            return super.onStartCommand(intent, flags, startId);
        }
    
        class Connection implements ServiceConnection {
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                // 服务绑定成功时回调
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                // 再次启动前台进程
                startService();
                // 绑定另外一个远程进程
                bindService();
            }
        }
    
        /**
         * API 18 ~ 25 以上的设备, 关闭通知到专用服务
         */
        public static class CancelNotificationService extends Service {
            public CancelNotificationService() {
            }
    
            @Override
            public void onCreate() {
                super.onCreate();
                startForeground(10, new Notification());
                stopSelf();
            }
    
            @Override
            public IBinder onBind(Intent intent) {
                return null;
            }
    
        }
    }
    


    4、清单配置


    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="kim.hsl.two_process_alive">
    
        <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/Theme.Two_Process_Alive">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
    
            <!-- 本地提权前台服务 Service -->
            <service
                android:name=".LocalForegroundService"
                android:enabled="true"
                android:exported="true"></service>
    
            <!-- 本地服务 , API 18 ~ 25 以上的设备, 关闭通知到专用服务 -->
            <service
                android:name=".LocalForegroundService$CancelNotificationService"
                android:enabled="true"
                android:exported="true"></service>
    
            <!-- 远程提权前台服务 Service -->
            <service
                android:name=".RemoteForegroundService"
                android:enabled="true"
                android:exported="true"
                android:process=":remote"></service>
    
            <!-- 远程服务 , API 18 ~ 25 以上的设备, 关闭通知到专用服务 -->
            <service
                android:name=".RemoteForegroundService$CancelNotificationService"
                android:enabled="true"
                android:exported="true"
                android:process=":remote"></service>
    
        </application>
    
    </manifest>
    


    5、启动两个服务


    package kim.hsl.two_process_alive;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.content.Intent;
    import android.os.Bundle;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 通过前台 Service 提升应用权限
            // 启动普通 Service , 但是在该 Service 的 onCreate 方法中执行了 startForeground
            // 变成了前台 Service 服务
            startService(new Intent(this, LocalForegroundService.class));
            startService(new Intent(this, RemoteForegroundService.class));
        }
    }
    


    5、执行效果


    执行上述应用后 , 可以看到启动了两个应用 , 干掉应用后 , 可以被远程进程拉起 , 干掉远程进程 , 远程进程可以本主进程服务拉起 ;

    在这里插入图片描述





    三、 源码资源



    源码资源 :

    展开全文
  • 双进程守护需要通过一个进程保活另一个进程,当两个进程中其中一个被kill掉时,另一个会重启被kill掉的进程,从而保证子子孙孙无穷无尽。一个进程需要知道另一个进程的状态,需要实现进程间通信aidl。然后我们需要...
    29117276684ac9864d130e4df847a90f.png

    双进程守护需要通过一个进程保活另一个进程,当两个进程中其中一个被kill掉时,另一个会重启被kill掉的进程,从而保证子子孙孙无穷无尽。一个进程需要知道另一个进程的状态,需要实现进程间通信aidl。然后我们需要后台服务唤醒进程,同时可以在后台做一些悄悄的事情,系统又杀不死,于是被认为是流氓软件,像qq微信也是这样的。但是随着安卓版本提升,这种方式也开始失效了。当一个服务被系统杀死却重启多次后,他就真的死了(相当于在正在运行界面手中杀死他)。如果是意外被杀死非系统主动杀死而服务是sticky的话,系统反而会认为服务意外停止而重启他。

    以往尝试让服务长时间存活在后台的方式是在一个进程里建立两个服务让他们相互监听,当其中一个服务被杀死时,另一个服务重新启动被杀死的服务。但是因为在同一个进程中,当进程被杀死,服务也终止,因为服务属于进程。这就为和双进程那么重要。

    首先定义aidl文件,因为不需要具体交互数据,所以方法随便来一个就行。

    98b781d14e88b4795cd739fa75bd25b7.png

    aidl文件所在目录必须保证包名结构和对应服务报名目录结构一致。下面是aidl文件内容:

    1cc6550aa0f9c05e86ed189dcf1ec8c2.png

    包名必须和所在目录包名一致,接口名称和定义的方法根据实际需求而定,这里没有要求。

    下面是两个aidlservice:

    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 {

    final String TAG=this.getClass().getSimpleName();

    IBinder binder=new Record.Stub() {

    @Override

    public String getName() throws RemoteException {

    return TAG;

    }

    };

    @Override

    public IBinder onBind(Intent intent) {

    return binder;

    }

    ServiceConnection conn;

    @Override

    public void onCreate() {

    super.onCreate();

    if(conn==null) {

    conn = new ServiceConnection() {

    @Override

    public void onServiceConnected(ComponentName name, IBinder service) {

    Record record = Record.Stub.asInterface(service);

    try {

    Log.e(TAG, record.getName());

    } catch (RemoteException e) {

    e.printStackTrace();

    }

    }

    @Override

    public void onServiceDisconnected(ComponentName name) {

    startService(new Intent(LocalService.this, RemoteService.class));

    bindService(new Intent(LocalService.this, RemoteService.class), conn, Context.BIND_IMPORTANT);

    Log.e(TAG, "重新绑定了远程服务");

    }

    };

    }

    }

    @Override

    public int onStartCommand(Intent intent, int flags, int startId) {

    LocalService.this.bindService(new Intent(LocalService.this, RemoteService.class), conn, Context.BIND_IMPORTANT);

    Log.e(TAG,"本地服务绑定了远程服务");

    return START_STICKY;

    }

    @Override

    public void onDestroy() {

    super.onDestroy();

    unbindService(conn);

    }

    }

    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 {

    final String TAG=this.getClass().getSimpleName();

    IBinder binder=new Record.Stub() {

    @Override

    public String getName() throws RemoteException {

    return TAG;

    }

    };

    @Override

    public IBinder onBind(Intent intent) {

    return binder;

    }

    ServiceConnection conn;

    @Override

    public void onCreate() {

    super.onCreate();

    if(conn==null){

    conn=new ServiceConnection() {

    @Override

    public void onServiceConnected(ComponentName name, IBinder service) {

    Record record=Record.Stub.asInterface(service);

    try {

    Log.e(TAG,record.getName());

    } catch (RemoteException e) {

    e.printStackTrace();

    }

    }

    @Override

    public void onServiceDisconnected(ComponentName name) {

    startService(new Intent(RemoteService.this,LocalService.class));

    bindService(new Intent(RemoteService.this,LocalService.class),conn,Context.BIND_IMPORTANT);

    Log.e(TAG,"重新绑定了本地服务");

    }

    };

    }

    }

    @Override

    public int onStartCommand(Intent intent, int flags, int startId) {

    RemoteService.this.bindService(new Intent(RemoteService.this, LocalService.class), conn, Context.BIND_IMPORTANT);

    Log.e(TAG,"远程服务绑定本地服务");

    return START_STICKY;

    }

    @Override

    public void onDestroy() {

    super.onDestroy();

    unbindService(conn);

    }

    }

    他们基本上是一样的,功能只是在对方被kill掉时启动对方。重点是这两个service必须在不同进程中,所以需要在配置中指定其中一个service独立的process,名称随意。

    ab6a4192913b2a4e6dd2085a54a62344.png

    这样就拥有两个进程了。并且通过了aidl进行进程间通信,可以监听到另一个服务的终止,比如上面某个服务中的:

    ecf416b9db91d7d2a7c19e423382c708.png

    从服务连接中可以在另一个服务被kill时启动他,并绑定他。

    因为在启动对方的时候对方会对当前服务进行绑定,所以这里只需要再次调用本身绑定对方,形成闭环,子子孙孙无穷无尽。

    理论上这种方式可以让服务永留后台,但是实际上多次在正在运行任务界面杀死多次后就再也无法起来了。有可能高版本的api已经禁止了这种流氓行为。也有可能只是因为频繁关闭服务导致其中一个服务还没启动就关闭了另一个服务,所以就没有服务拉起了。但也有可能是我手速太快,系统卡顿造成服务没有绑定好另一个服务,就被我再次kill了。或者服务还没有重启完全就被kill,因为用到aidl,aidl比较耗时。

    qq微信也是用的双进程甚至多进程,但是主要是大厂对安卓系统做了定制,预制应用有安卓系统保活,后台服务杀不死是合法的流氓行为。

    但是网上还可以找到比较零散的方式对后台服务进行保活。

    1.在服务的onStartCommand返回sticky标签,这个当服务被意外kill时系统会重启他,但是进程被kill服务自然被kill,用处不大。

    @Override

    public int onStartCommand(Intent intent, int flags, int startId) {

    flags = START_STICKY;

    return super.onStartCommand(intent, flags, startId);

    }

    3.当服务处于一些回调状态比如onStartCommand和onDestroy等时会处于前台,处于前台的服务更不容易被kill

    在onStartCommand回调中将服务放到前台

    Notification notification = new Notification(R.drawable.ic_launcher,

    getString(R.string.app_name), System.currentTimeMillis());

    PendingIntent pendingintent = PendingIntent.getActivity(this, 0,

    new Intent(this, AppMain.class), 0);

    notification.setLatestEventInfo(this, "uploadservice

    展开全文
  • 【Android 进程保活】应用进程拉活 ( 双进程守护 + JobScheduler 保活 | 成功率最高 | 推荐使用 ) https://hanshuliang.blog.csdn.net/article/details/115607584 博客源码快照

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 485
精华内容 194
关键字:

双进程守护