본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] JobScheduler 의 schedule 이 fail 하는 케이스

by 돼지왕 왕돼지 2018. 4. 29.
반응형

[android] JobScheduler 의 schedule 이 fail 하는 케이스


Android, binder, jobscheduler, jobscheduler schedule fail, JobSchedulerImpl, JobSchedulerService, JobSchedulerStub, RemoteException, RESULT_FAILURE, RESULT_SUCCESS, Schedule, [android] JobScheduler 의 schedule 이 fail 하는 케이스


Framework 소스 코드 기준은 LOS 5.0.0_r2 ~ MOS 6.0.1_r10


-

schedule method 는 RESULT_FAILURE(0) 또는 RESULT_SUCCESS(1) 값 중 하나를 return 한다.



-

JobScheduler 은 abstract class 이고, 실제 구현 내용은 JobSchedulerImpl 에 있다.

해당 코드를 보면 binder 를 통해 schedule 명령을 내리게 되고, 명시적으로 RemoteException 이 발생하면 fail 이 발생한다.

@Override

    public int schedule(JobInfo job) {

        try {

            return mBinder.schedule(job);

        } catch (RemoteException e) {

            return JobScheduler.RESULT_FAILURE;

        }

    }



-

그럼 binder.schedule 에서 RemoteException 외에 false 를 return 하는 케이스가 또 있지 않을까?

JobSchedulerImpl 에서 사용하는 binder 객체는 JobSchedulerService 의 inner class 로 있는 JobSchedulerStub 이다.

@Override

public int schedule(JobInfo job) throws RemoteException {

    if (DEBUG) {

        Slog.d(TAG, "Scheduling job: " + job.toString());

    }

    final int pid = Binder.getCallingPid();

    final int uid = Binder.getCallingUid();


    enforceValidJobRequest(uid, job);

    if (job.isPersisted()) {

        if (!canPersistJobs(pid, uid)) {

            throw new IllegalArgumentException("Error: requested job be persisted without"

                    + " holding RECEIVE_BOOT_COMPLETED permission.");

        }

    }


    long ident = Binder.clearCallingIdentity();

    try {

        return JobSchedulerService.this.schedule(job, uid);

    } finally {

        Binder.restoreCallingIdentity(ident);

    }

}


나머지 코드에서 exception 이 발생하지 않는다면 결국 JobSchedulerService 자체에 있는 schedule 코드에서의 return 결과를 확인해봐야 한다.

public int schedule(JobInfo job, int uId) {

    JobStatus jobStatus = new JobStatus(job, uId);

    cancelJob(uId, job.getId());

    startTrackingJob(jobStatus);

    mHandler.obtainMessage(MSG_CHECK_JOB).sendToTarget();

    return JobScheduler.RESULT_SUCCESS;

}


 에러가 없는 한 JobScheduler.RESULT_SUCCESS 가 return 된다.

결국 FAIL 이 발생하는 케이스는 RemoteException 이 발생했을 때 뿐이라고 추정할 수 있다.




반응형

댓글