Android JobScheduling - мне нужно передать объект на мою работу, но как?

Я хотел бы использовать Androids new JobScheduler в своем приложении, но сейчас я не знаю, как передать мой объект, который содержит данные (массив byte), который должен быть отправлен через сеть по заданию. Я искал ответ, но пока не нашел никого, кого я боюсь.

У меня есть 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);
        }
    }
}

... создаю такую ​​работу:

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(работа);

... и планирую задание:

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

Sooo... Я не могу вызвать какие-либо методы в MyJob напрямую, не так ли? Затем я подумал, что могу использовать .setExtras(bundle) для передачи моего объекта в задание, но, как я узнал, вы можете использовать только PersistableBundle, который не будет использовать сериализованный объект, например Bundle. Установка ключей и значений не работает, потому что вы можете поместить только booleans, ints, strings и т.д., Но не byte[], что мне нужно.

Есть ли у кого-нибудь идеи? Я совсем застрял.

Спасибо заранее, а-т

PS: Извините, если я, вероятно, не использовал правильные коды-теги.

Ответ 1

Хорошо - я отвечу сам.

Похоже, что передача более сложных объектов, чем String, ints и т.д. в JobService, невозможна из-за причин персистентности (код мог быть изменен, а не классы не смогут работать со старыми данными). Это, конечно, имеет смысл, но я считаю, что с этим ограничением очень сложно использовать JobScheduling.

Мое "решение" теперь сохраняет мой объект в файле и передает имя файла через

PersistableBundle bundle = new PersistableBundle();
bundle.putString("filename", object.getFilename());

В моем JobService я читаю этот файл и отправляю его по сети. Может быть, это не очень элегантно, но я не могу придумать другого (лучшего) способа. Возможно, это помогает кому-то.

Ответ 2

Я знаю, что это старый вопрос, но я оставлю свое решение для тех, кто считает это полезным.

Сначала я превращаю свой объект в json с помощью Gson

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

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

Затем вы извлекаете строку из пакета и десериализуете

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

Ответ 3

Я попробовал это, но с помощью FirebaseJobDispatcher: 1- я сделал свой CustomObject реализующим Parcelable 2- я преобразовал свой CustomObject в строку 3- я положил его как дополнительный в Bundle

хранить данные:

    private String encodeToString(CustomObject customObject) {
        Parcel parcel = Parcel.obtain();
        List< CustomObject > temp = new ArrayList<>();
        temp.add(customObject);
        parcel.writeList(temp);
        byte[] byt = parcel.marshall();
        String data = Base64.encodeToString(byt, 0, byt.length, 0);
        parcel.recycle();

        return data;
    }

чтобы получить данные:

       private CustomObject decodeFromString (String data) {
            byte[] byt = Base64.decode(data, 0);

            Parcel parcel = Parcel.obtain();
            parcel.unmarshall(byt, 0, byt.length);
            parcel.setDataPosition(0);

            List<CustomObject> temp = new ArrayList<>();
            parcel.readList(temp, getClass().getClassLoader());
            parcel.recycle();

            if (temp.size()>0) {
                return temp.get(0);
            } else {
                return null;
            }
        }