美文网首页
Android O上service保活方案

Android O上service保活方案

作者: breaktian | 来源:发表于2019-05-14 18:31 被阅读0次

    从android O版本开始,google为了控制资源使用增加了两项后台限制:

    • 后台服务
    • 广播

    今天主要说后台服务

    其中对于后台服务的限制,指的是如果应用处于后台,则不允许直接使用startService
    可以使用新增的startForgroundService api启动前台服务(在调用此api之后5s之内必须调用startFroground启动前台服务通知)

    那什么是后台应用?后台的对立面是前台,google对于前台的定义如下:

    • 具有可见的activity(不管该activity已启动还是已暂停)
    • 具有前台服务
    • 有关联的前台应用(如壁纸,通知侦听器等)

    具体可参考官方链接:

    https://developer.android.com/about/versions/oreo/background

    思路:如果app在前台的时候,service一般不会被干掉,切到后台只能存活1分钟左右就会被系统干掉,当service被干掉就会执行onDestory方法,在onDestory中启动一个1像素的activity,这个activity启动之后去重新启动下service,然后finish(不能直接在onDestory中启动service,会报错),这样就能保证service在后台长时间存活

    废话不多说,直接上代码:

    public class FirstService extends Service {
    
        private final String TAG = "FirstService";
    
        public static void start(Context context){
            Intent intent = new Intent(context, FirstService.class);
            AndroidOAdapter.startService(context, intent);
        }
    
        Handler handler = new Handler();
    
        int count = 0;
    
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                Log.d(TAG,"FirstService running "+count++);
                if (count==10) SecondService.start(FirstService.this);
                handler.postDelayed(this, 1000);
            }
        };
    
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.d(TAG,"onCreate... ");
            handler.post(runnable);
    
    //        bindSecondService();
    
        }
    
    //    private void bindSecondService() {
    //        bindService(new Intent(this, SecondService.class), new ServiceConnection() {
    //            @Override
    //            public void onServiceConnected(ComponentName name, IBinder service) {
    //                Log.d(TAG,"onServiceConnected ");
    //                SecondService secondService = ((SecondService.LocalBinder) service).getService();
    //
    //                AndroidOAdapter.startForeground(secondService);
    //                AndroidOAdapter.startForeground(FirstService.this);
    //                secondService.stopForeground(true);
    //                FirstService.this.unbindService(this);
    //            }
    //
    //            @Override
    //            public void onServiceDisconnected(ComponentName name) {
    //                Log.d(TAG,"onServiceDisconnected ");
    //            }
    //        }, Service.BIND_AUTO_CREATE);
    //    }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            Log.d(TAG,"onStartCommand... ");
    
            return START_STICKY;
        }
    
    
        @Override
        public void onDestroy() {
            Log.d(TAG,"onDestroy....");
            handler.removeCallbacks(runnable);
            AndroidOAdapter.onServiceDestory(this);
            super.onDestroy();
        }
    }
    
    public class AndroidOServiceHelpActivity extends Activity {
    
        public static String EXTRA_COMPONENT_NAME = "componentName";
    
        public static void start(Context context, ComponentName componentName){
            Intent intent = new Intent(context, AndroidOServiceHelpActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra(EXTRA_COMPONENT_NAME, componentName);
            context.startActivity(intent);
        }
    
        private String tag = this.getClass().getSimpleName();
    
        Handler handler = new Handler();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setOnePixLayout();
            Log.d(tag,"onCreate...");
    
            onStartService(getIntent());
    
        }
    
        @Override
        protected void onNewIntent(Intent intent) {
            onStartService(intent);
        }
    
        private void onStartService(Intent intent) {
            Log.d(tag,"onStartService...");
            if(intent!=null){
                ComponentName componentName = intent.getParcelableExtra(EXTRA_COMPONENT_NAME);
                if(componentName!=null){
                    Intent serviceIntent = new Intent();
                    serviceIntent.setComponent(componentName);
                    startService(serviceIntent);
                    finish();
                }
            }
            finish();
        }
    
        private void setOnePixLayout() {
            //设置1像素
            Window window = getWindow();
            window.setGravity(Gravity.LEFT | Gravity.TOP);
            WindowManager.LayoutParams params = window.getAttributes();
            params.x = 0;
            params.y = 0;
            params.height = 1;
            params.width = 1;
            window.setAttributes(params);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                    |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            Log.d(tag,"onResume...");
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            Log.d(tag,"onDestroy...");
        }
    
        @Override
        protected void onPause() {
            super.onPause();
            Log.d(tag,"onPause...");
        }
    
        @Override
        protected void onStop() {
            super.onStop();
            Log.d(tag,"onStop...");
        }
    
    //    @Override
    //    public void onBackPressed() {
    //
    //    }
    }
    
    public class AndroidOAdapter {
    
    
        public static void onServiceDestory(Service service){
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && BaseApplication.getAppContext().getApplicationInfo().targetSdkVersion >= 26) {
                AndroidOServiceHelpActivity.start(service, new ComponentName(service, service.getClass()));
            }
        }
    }
    
    这种方式需要后台弹出权限(小米和vivo),华为好像没有这个权限,但是小米5s上我测试了这个权限默认是给打开的

    相关文章

      网友评论

          本文标题:Android O上service保活方案

          本文链接:https://www.haomeiwen.com/subject/ktyeaqtx.html