Android JobScheduling - I need to pass an object to my job but how?

a-m picture a-m · Nov 27, 2015 · Viewed 12k times · Source

I would like to use Androids new JobScheduler in my app but right now I don't know how to pass my object which contains the data (byte array) that should be sent via network by a job. I searched for an answer but so far found none I'm afraid.

I have a JobService:

public class MyJob extends JobService {

    @Override
    public boolean onStartJob(JobParameters jobParameters) {
        new JobTask(this).execute(jobParameters);
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return false;
    }

    private static class JobTask extends AsyncTask<JobParameters, Void,       JobParameters> {
        private final JobService jobService;

        public JobTask(JobService jobService) {
            this.jobService = jobService;
        }

        @Override
        protected JobParameters doInBackground(JobParameters... params) {
            AnotherClass.post(myObject); // where does myObject come from?
            return params[0];
        }

        @Override
        protected void onPostExecute(JobParameters jobParameters) {
            jobService.jobFinished(jobParameters, false);
        }
    }
}

... am building a job like this:

PersistableBundle bundle = new PersistableBundle();
JobInfo job = new JobInfo.Builder(jobID, new ComponentName(context, AshServiceJob.class))
              .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
              .setPersisted(true)
              .setExtras(bundle)  // could bundle somehow contain myObject?
              .build();

OtherClass.addJobInBackground(job);

... and am scheduling the job:

public void addJobInBackground(final JobInfo job) {
        JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
        jobScheduler.schedule(job);
    }

Sooo ... I can't call any methods in MyJob directly, right? I then thought I could use .setExtras(bundle) to pass my object to the job, but as I found out you can only use a PersistableBundle which wouldn't take a serialized object like Bundle. Setting keys and values doesn't work, because you can only put booleans, ints, strings, etc. but not byte[], which is what I need.

Has anyone any idea? I'm quite stuck.

Thanks in advance, a-m

PS: Sorry, if I probably didn't use the right Code-Tags.

Answer

Tulio F. picture Tulio F. · Mar 22, 2016

I know it is an old question, but I'll leave my solution for whoever finds it useful.

First I turn my object into json using the Google Gson library

MyCustomObject myObj = new MyCustomObject("data1", 123);
Gson g = new Gson();
String json = g.toJson(myObj);

PersistableBundle bundle = new PersistableBundle();
bundle.putString("MyObject", json);

Then you retrieve the string from the bundle and deserialize

String json = params.getExtras().getString("MyObject");
Gson g = new Gson();
MyCustomObject myObj = g.fromJson(json, MyCustomObject.class);