Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 694
a-m Avatar asked Nov 27 '15 12:11

a-m


People also ask

How does JobScheduler work in Android?

JobScheduler is introduced while the Android set limitation on background Execution. It means that the system will automatically destroy the background execution to save battery and memory. So if you want to perform some background job like some network operations no matter your app is running or not.

Is JobScheduler deprecated?

Evolution in Android fundamentals Now onwards Job Scheduler already deprecated for next version of Android so now we have WorkManager instead.

What is Jobservice?

This service executes each incoming job on a Handler running on your application's main thread. This means that you must offload your execution logic to another thread/handler/ AsyncTask of your choosing. Not doing so will result in blocking any future callbacks from the JobManager - specifically onStopJob(android.


1 Answers

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);
like image 168
Tulio F. Avatar answered Sep 20 '22 14:09

Tulio F.