アプリでAndroidの新しい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(job);
...そしてジョブをスケジュールしています:
_public void addJobInBackground(final JobInfo job) {
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(job);
}
_
Sooo ... MyJobでメソッドを直接呼び出すことはできませんよね?次に、.setExtras(bundle)
を使用してオブジェクトをジョブに渡すことができると思いましたが、わかったように、バンドルのようなシリアル化されたオブジェクトを取得できないPersistableBundle
しか使用できません。 _booleans, ints, strings
_などのみを配置でき、_byte[]
_は配置できないため、キーと値の設定は機能しません。これが必要です。
誰かアイデアはありますか?私はかなり立ち往生しています。
よろしくお願いします。
PS:申し訳ありませんが、おそらく正しいコードタグを使用していなかったとしたら。
わかりました-私は自分で答えます。
永続性の理由により、String、intなどより複雑なオブジェクトをJobServiceに渡すことはできないようです(コードが変更されている可能性があり、クラスが古いデータを処理できないため)。もちろんそれは理にかなっていますが、私はその制限によりJobSchedulingを使用することは非常に難しいと思います。
私の「解決策」は、オブジェクトをファイルに保存し、ファイル名を
PersistableBundle bundle = new PersistableBundle();
bundle.putString("filename", object.getFilename());
私のJobServiceでは、そのファイルを読み取り、ネットワーク経由でデータを送信しています。多分それは本当にエレガントではないかもしれませんが、私は別の(より良い)方法を考えることができません。多分これは誰かを助ける。
私はそれが古い質問であることを知っていますが、それが有用であると思う人のために私の解決策を残します。
まず、Googleを使用してオブジェクトを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);
私はそれを試しましたが、FirebaseJobDispatcherで:
Parcelableを拡張するCustomObjectをStringに変換するには:
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;
}
文字列から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;
}
}