• 性能优化-service进程防杀


    service作为后台服务,其重要性不言而喻,但很多时候service会被杀死,从而失去了我们原本想要其发挥的作用,在这种情况下我们该如何确保我们的service不被杀死就是本节需要讨论的内容了

    service的等级说明

    在了解service的等级说明以后,明白其生命周期,有助于我们更好的去做好服务
    常见的分类是将进程分成五个等级,等级越高越不容易被系统干掉,那么先来看一看进程都有些什么等级吧

    • 前台进程
      当某个Activity处于前台并且正在活动的时候,那么这个Activity就属于前台进程,此时是不会被回收的,那么这个Activity所绑定的service也属于前台进程,也不会被回收;service被主动调为前台进程的时候(startForeground()),这时候这个服务也属于前台进程

    • 可见进程
      当Activity处于onPause()阶段,但尚未进入到onStop()阶段的时候,绑定其活动的service也属于可见进程

    • 服务进程
      使用startService()启动的进程属于服务进程,是普通的进程

    • 后台进程
      在布局文件中通过android:process=":xxx"指定的进程属于后台进程

    • 空进程
      不含任何活动组件的进程

    进程优先级的提高方案

    要想线程不被轻易杀死,就要尽可能的提高线程的优先级,那么有哪些切实可行的解决方案呢

    1. 系统白名单
    2. 双进程守护
    3. JobScheduler系统任务调度
    4. 监听其他app的广播启动
    5. 利用账号同步机制启动

    进程防杀示例

    Java层双进程守护

    双进程守护可以通过Java层实现,也可以通过Native层实现
    这里使用Java层的示例
    首先编写aidl文件,确保两个service之间能够通信

    interface ConnectionInterface {
        String getProcessName();
    }
    

    编写service,这里有两个,其代码几乎一样,这里就只贴一个

    public class ServiceTwo extends Service {
    
        private static final String TAG = "ServiceTwo";
        private MyBinder myBinder;
        private ServiceConnection connection;
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return myBinder;
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            if(myBinder == null){
                myBinder = new MyBinder();
            }
            connection = new MyServiceConnection();
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            ServiceTwo.this.bindService(new Intent(ServiceTwo.this, ServiceOne.class),connection,Context.BIND_IMPORTANT);
    		//这里使用一个通知将Server放到前台去了
            PendingIntent contentIntent = PendingIntent.getService(this, 0, intent, 0);
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
            builder.setTicker("test")
                    .setContentIntent(contentIntent)
                    .setContentTitle("ForTest")
                    .setAutoCancel(true)
                    .setContentText("ServiceTwo")
                    .setWhen( System.currentTimeMillis());
            startForeground(startId,builder.build());
            return  START_STICKY;
        }
    
        class MyBinder extends ConnectionInterface.Stub{
    
            @Override
            public String getProcessName() throws RemoteException {
                return "ServiceTwo";
            }
        }
    
        class MyServiceConnection implements ServiceConnection{
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                Log.e(TAG,"连接成功");
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.d(TAG, "断开连接");
                ServiceTwo.this.startService(new Intent(ServiceTwo.this, ServiceOne.class));
                ServiceTwo.this.bindService(new Intent(ServiceTwo.this,ServiceOne.class),connection, Context.BIND_IMPORTANT);
            }
        }
    }
    

    然后在activity中直接使用startService()启动两个服务即可
    编译安装发现两个服务都在运行,停止其中一个,另一个立马将其唤醒
    这种情况如果直接停掉应用,那么两个Service都会被杀死,那么使用系统任务调度,就可以将其唤醒了···,说实话,这个真的就有点流氓了
    Service被系统杀死,那么可以使用JobService将其唤醒
    不过这个是从SDK21才开始支持的一个系统服务
    其也有固有缺陷。不能频繁调用

  • 相关阅读:
    ORA-27302: failure occurred at: sskgpsemsper
    mysql 慢查询设置
    静默安装ORACLE数据库软件
    启动服务器上的所有oracle数据库
    shell tr 命令详解
    Hive安装
    hadoop2.7.2完全分布式环境搭建
    FastDFS
    aspnet_regiis加密文件提示路径中具有非法字符
    DataGridview绑定复杂对象
  • 原文地址:https://www.cnblogs.com/cj5785/p/10664630.html
Copyright © 2020-2023  润新知