Android JobScheduling - 我需要将一个对象传递给我的作业,但如何传递?
Android JobScheduling - I need to pass an object to my job but how?
我想在我的应用程序中使用 Android 的新 JobScheduler,但现在我不知道如何传递我的对象,其中包含作业应通过网络发送的数据(byte
数组) .
我搜索了答案,但到目前为止找到 none 恐怕。
我有一个工作服务:
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 这样的序列化对象。设置keys和values不行,因为只能放booleans, ints, strings
等,不能放byte[]
,这正是我需要的
有人知道吗?我卡住了。
提前致谢,
一米
PS:抱歉,我可能没有使用正确的代码标签。
好的 - 我会自己回答。
由于持久性原因,似乎无法将比字符串、整数等更复杂的对象传递给 JobService(代码可能已更改,而不是 类 将无法使用旧数据).
这当然是有道理的,但我认为在这种限制下很难使用 JobScheduling。
我的 "solution" 现在正在将我的对象保存在文件中并通过
传递文件名
PersistableBundle bundle = new PersistableBundle();
bundle.putString("filename", object.getFilename());
在我的 JobService 中,我正在读取该文件并通过网络发送它的数据。也许它不是很优雅,但我想不出另一种(更好)的方法。
也许这对某人有帮助。
我知道这是一个老问题,但我会把我的解决方案留给觉得有用的人。
首先,我使用 Google Gson 库
将我的对象变成 json
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);
我试过了,但是使用了 FirebaseJobDispatcher:
- 我使我的 CustomObject 实现 Parcelable
- 我将 CustomObject 转换为字符串
- 我把它作为捆绑包的额外内容
将扩展 Parcelable 的自定义对象转换为字符串:
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;
}
检索从 String 扩展 Parcelable 的 CustomObject:
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;
}
}
Class 如果自定义对象通过作业服务中的 Intent 传递,加载程序信息将丢失。
可以通过设置额外的class loader来解决
intent.setExtrasClassLoader(<CUSTOM CLASS>.class.getClassLoader());
我想在我的应用程序中使用 Android 的新 JobScheduler,但现在我不知道如何传递我的对象,其中包含作业应通过网络发送的数据(byte
数组) .
我搜索了答案,但到目前为止找到 none 恐怕。
我有一个工作服务:
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 这样的序列化对象。设置keys和values不行,因为只能放booleans, ints, strings
等,不能放byte[]
,这正是我需要的
有人知道吗?我卡住了。
提前致谢, 一米
PS:抱歉,我可能没有使用正确的代码标签。
好的 - 我会自己回答。
由于持久性原因,似乎无法将比字符串、整数等更复杂的对象传递给 JobService(代码可能已更改,而不是 类 将无法使用旧数据). 这当然是有道理的,但我认为在这种限制下很难使用 JobScheduling。
我的 "solution" 现在正在将我的对象保存在文件中并通过
传递文件名PersistableBundle bundle = new PersistableBundle();
bundle.putString("filename", object.getFilename());
在我的 JobService 中,我正在读取该文件并通过网络发送它的数据。也许它不是很优雅,但我想不出另一种(更好)的方法。 也许这对某人有帮助。
我知道这是一个老问题,但我会把我的解决方案留给觉得有用的人。
首先,我使用 Google Gson 库
将我的对象变成 jsonMyCustomObject 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);
我试过了,但是使用了 FirebaseJobDispatcher:
- 我使我的 CustomObject 实现 Parcelable
- 我将 CustomObject 转换为字符串
- 我把它作为捆绑包的额外内容
将扩展 Parcelable 的自定义对象转换为字符串:
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;
}
检索从 String 扩展 Parcelable 的 CustomObject:
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;
}
}
Class 如果自定义对象通过作业服务中的 Intent 传递,加载程序信息将丢失。
可以通过设置额外的class loader来解决
intent.setExtrasClassLoader(<CUSTOM CLASS>.class.getClassLoader());