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;
          }
      }

       

我這里就是簡單的示范一下,具體我們項目里面的實現並沒有發到上面,各位可以自己琢磨。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM