zoukankan      html  css  js  c++  java
  • Android--使用JobService实现进程保活

    进程保活一直是广大APP开发者所希望的,因为进程活着我们就可以操作很多事情(推送,数据同步等等),但是google大大是不允许这样做的(优化),所以我们要另辟蹊径。

    1. 先来看看android中有几种进程吧。
      • 前台进程:Foreground process
        • 用户正在交互的Activity(onResume())
        • 当某个Service绑定正在交互的Activity。
        • 被主动调用为前台Service(startForeground())
        • 组件正在执行生命周期的回调(onCreate()/onStart()/onDestroy())
        • BroadcastReceiver 正在执行onReceive();

      • 可见进程:Visible process
        • 我们的Activity处在onPause()(没有进入onStop())
        • 绑定到前台Activity的Service。
      • 服务进程:Service process
        • 简单的startService()启动。
      • 后台进程:Background process
        • 对用户没有直接影响的进程----Activity出于onStop()的时候。
          android:process=":xxx"

      • 空进程:Empty process
        • 不含有任何的活动的组件。(android设计的,为了第二次启动更快,采取的一个权衡)

      2、通常我们启动的都是一个服务进程,要么直接 startService() 要么 bindService(),我们可能需要在这些服务进程里面做一些事情,但这些事情并不是说我们现在要做的,可能是将来要做的,或者是在某个时间条件下要做的,这时候我们就需要我们的service保持活动状态。

      3、JobService 可以算是一个 JobScheduler 的回调服务。JobScheduler是一个系统级的作业调度器,我们将某些任务扔给系统,当达到我们设定的条件以后,JobScheduler再吊起我们的JobService执行我们的业务逻辑。

      4、接下来看看我们如何实现。(我就直接上代码了)

      • @SuppressLint("NewApi")
        public class JobHandleService extends JobService {
            private int kJobId = 0;
        
            @Override
            public void onCreate() {
                super.onCreate();
                Log.i("INFO", "jobService create");
            }
        
            @Override
            public int onStartCommand(Intent intent, int flags, int startId) {
                Log.i("INFO", "jobService start");
                // 在服务启动时,直接将任务推到JobScheduler 的任务队列,然后在设定的时间条件到达时,便会直接吊起我们的服务,走onStartJob()方法
                scheduleJob(getJobInfo());
                return START_NOT_STICKY;
            }
        
            @Override
            public void onDestroy() {
                super.onDestroy();
            }
        
            @Override
            public boolean onStartJob(JobParameters params) {
        //        params.getExtras()
        //        scheduleJob(getJobInfo());
                boolean isLocalServiceWork = isServiceWork(this, "com.xxx.XxxService");
                boolean isRemoteServiceWork = isServiceWork(this, "com.xxx.XxxService");
        
                if (!isLocalServiceWork || !isRemoteServiceWork) {
                    this.startService(new Intent(this, LocalService.class));
                    this.startService(new Intent(this, RemoteService.class));
                    Toast.makeText(this, "process start", Toast.LENGTH_SHORT).show();
                }
                return true;
            }
        
            @Override
            public boolean onStopJob(JobParameters params) {
                Log.i("INFO", "job stop");
                // 当执行完毕时,我们再将任务加入到 JobScheduler 里面就可以了。
                scheduleJob(getJobInfo());
                return true;
            }
        
            /**
             * Send job to the JobScheduler.
             */
            public void scheduleJob(JobInfo t) {
                Log.i("INFO", "Scheduling job");
                JobScheduler tm = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
                if (tm != null) {
                    tm.schedule(t);
                }
            }
        
            public JobInfo getJobInfo() {
                JobInfo.Builder builder = new JobInfo.Builder(kJobId++, new ComponentName(this, JobHandleService.class));
                builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
                builder.setPersisted(true);
                builder.setRequiresCharging(false);
                builder.setRequiresDeviceIdle(false);
                builder.setPeriodic(10);//间隔时间--周期
                return builder.build();
            }
        
        
            /**
             * 判断某个服务是否正在运行的方法
             *
             * @param mContext
             * @param serviceName 是包名+服务的类名(例如:net.loonggg.testbackstage.TestService)
             * @return true代表正在运行,false代表服务没有正在运行
             */
            public boolean isServiceWork(Context mContext, String serviceName) {
                boolean isWork = false;
                ActivityManager myAM = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
                List<RunningServiceInfo> myList = null;
                if (myAM != null) {
                    myList = myAM.getRunningServices(100);
                }
                if (myList != null && myList.size() <= 0) {
                    return false;
                }
                if (myList != null) {
                    for (int i = 0; i < myList.size(); i++) {
                        String mName = myList.get(i).service.getClassName();
                        if (mName.equals(serviceName)) {
                            isWork = true;
                            break;
                        }
                    }
                }
                return isWork;
            }
        }

    我这里就是简单的示范一下,具体我们项目里面的实现并没有发到上面,各位可以自己琢磨。

  • 相关阅读:
    如何用kaldi做孤立词识别三
    如何用kaldi做孤立词识别二
    脚本注释3
    [转] kaldi中FST的可视化-以yesno为例
    如何用kaldi做孤立词识别-初版
    [转]语言模型训练工具SRILM
    [转]kaldi 神经网络
    [转]kaldi ASR: DNN训练
    [转]Kaldi命令词识别
    [转] 如何用kaldi训练好的模型做特定任务的在线识别
  • 原文地址:https://www.cnblogs.com/819158327fan/p/9306415.html
Copyright © 2011-2022 走看看