読者です 読者をやめる 読者になる 読者になる

ノラプログラマーの技術メモ

ネットで調べても出てこなかった情報を載せていきたい技術系ブログ。

【android開発】intentで値が変わる時の対処方法

概要

android開発で通知やサービスなどを利用する時に、intentに値を渡してアクティビティ間でデータをやり取りすることがあると思う。

中でもPendingIntentを使っていると、intentに引数として渡した値(つまりputExtra関数でセットした値)が、受け取るActivity側で値が変わってしまう時がある。

正確には古いデータが使われてしまうので、値が変わらないように見える。この辺はandroid開発者の鬼門とも言うべき箇所だと思うので、その解決法をメモしておく。

プログラム

一般的には、次のようなソースコードが書かれるはず。ネットで調べると以下のサンプルが多いけど、実はこれは非常にダメな書き方なのだ。

Intent intent = new Intent(context, WidgetConfigure.class);
intent.putExtra("PARAM", 1);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

試しに上記をアクティビティで受けてみる。getIntExtra関数で値が取得できる。すると値が変わるのが分かる。つまりPARAMの値が1となるはずが、そうはならないのだ。

ではどうするか?正しくは次のようにする。

Intent intent = new Intent(context, WidgetConfigure.class);
intent.putExtra("PARAM", 1);
int randam_id = (int)(Math.random()*100000);
PendingIntent pendingIntent = PendingIntent.getActivity(context, randam_id, intent, PendingIntent.FLAG_UPDATE_CURRENT);

PendingIntentの第2引数に一意な数字を指定する。そうすることでIDが被らないので渡した値が別々のインスタンスで管理される。最初のコードだと常に0を指定しているので、古いインスタンスを使いまわしてしまうのだ。

次に第4引数にPendingIntent.FLAG_UPDATE_CURRENTを指定する。これにより、仮にIDが被った場合でも古いインスタンスの情報を上書き更新してくれる。

ドキュメントには第二引数は今は使われていないと書かれているけど、実際には使われているのが落とし穴。これはハマる…。