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