17

アプリで 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(ジョブ);

...そして、ジョブをスケジュールしています:

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

すっごい… MyJob のメソッドを直接呼び出すことはできませんよね?次に、オブジェクトをジョブに渡すために使用できると考えましたが、バンドルのようなシリアル化されたオブジェクトを取らない.setExtras(bundle)a のみを使用できることがわかりました。キーと値の設定は機能しません。これは、などPersistableBundleしか配置できず、必要なものではないためです。booleans, ints, stringsbyte[]

誰にもアイデアはありますか?私はかなり立ち往生しています。

よろしくお願いします。

PS: 申し訳ありませんが、おそらく適切なコード タグを使用していない場合。

4

4 に答える 4

16

私はそれが古い質問であることを知っていますが、それが役に立つと思う人のために私の解決策を残します.

まず、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);
于 2016-03-22T20:03:07.757 に答える
7

わかりました-私は自分自身に答えます。

永続性の理由により、文字列、int などよりも複雑なオブジェクトを JobService に渡すことはできないようです (コードが変更されている可能性があり、クラスでは古いデータを処理できません)。もちろんそれは理にかなっていますが、その制限があるため、JobScheduling を使用するのは非常に難しいと思います。

私の「解決策」は、オブジェクトをファイルに保存し、ファイル名を介して渡すことです

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

私の JobService では、そのファイルを読み取り、ネットワーク経由でデータを送信しています。あまりエレガントではないかもしれませんが、別の (より良い) 方法は考えられません。多分これは誰かを助けるでしょう。

于 2015-12-03T10:04:54.877 に答える
0

私はそれを試しましたが、FirebaseJobDispatcher で:

  1. CustomObject に Parcelable を実装させました
  2. CustomObject を String に変換しました
  3. おまけとしてBundleに入れました

Parcelable を String に拡張する CustomObject を変換するには:

    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;
            }
        }
于 2019-01-15T13:53:57.313 に答える