流れとしてはこんな感じ
1.アプリAからIntentでアプリBを呼び出す。
その時、Intent#putExtraで付加情報をつける。
で、Activity#startActivtyする。
2.アプリBでなんか処理をしてfinishで終了する。
この時、当然Intent#getIntExtra系のメソッドで1で付加した情報が読める。
3.Homeキー長押しから再度アプリBを起動する。
4.アプリBでIntent#getIntExtra系のメソッドでまた1で付加した情報が読めてしまう。
4'.ランチャーから起動した場合は読めなくなってる。
試してみたこと
a.アプリBでIntent#removeExtraで該当の情報を消す
b.アプリBでIntent#putExtraで該当の情報を上書き
c.アプリBでActivity#setIntent(new Intent())で上書き
d.アプリBでFLAG_ACTIVITY_NO_HISTORYフラグを付けて呼び出す。(2011/1/31追記)
(c , dでアイデアくれてお二人ありがとうございます。)
残念ながらどれも失敗。
Activityのソース見たほうが早いんじゃない?ってアドバイスもらったのでサラッと見て見てみました。
おそらくですが、タスクを管理している所からインテントのインスタンスをもらっていました。
なので、試してみたことcは当然ダメなのですがaとbは効いてもよさそうなのに効かないので本当の実態は別でいるのではないかと予想してます。つまりクラスのコピーが渡ってきてる。
ホームキー長押しの履歴機能は当時の呼び出し状況をそのまま再現している勢いに見えます。(2011/1/31追記) 強調しますが適当に予想してますので事実とは全く違う可能性大です。
とは言いつつもこの動きのままではいろいろと困るので若干弱点というか未検証の部分があるものの対策を考えました。
簡単に言うと、呼び出すときにタイムスタンプを付けて同じ情報を2度拾わないって方法です。
前回の情報はアプリケーションクラスに保存します。
具体的には以下のような感じ。
と、言ってもサンプルすらいらないと思いますが。(しかも端折ってる。)
呼び出し方
Intent intent = new Intent();
intent.setAction("jp.hogehoge.ACTION_HOGE");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("FLAG", true);
intent.putExtra("TIMESTAMP", System.currentTimeMillis()); //これタイムスタンプ
startActivity(intent);
呼び出され方
public class HogeApplication extends Application {
private long _prevTimestamp = 0; //前回のタイムスタンプ
/**
* 前回のタイムスタンプ
* @param _prevTimestamp the _prevTimestamp to set
*/
public void setPrevTimestamp(long _prevTimestamp) {
this._prevTimestamp = _prevTimestamp;
}
/**
* 前回のタイムスタンプ
* @return the _prevTimestamp
*/
public long getPrevTimestamp() {
return _prevTimestamp;
}
}
public class HogeActivity extends Activity
private void checkIntent(){
Intent intent = getIntent();
HogeApplication app = (HogeApplication)getApplication();
if(intent == null){
}else if(app == null){
}else{
boolean flg = intent.getBooleanExtra("FLAG", false));
long timestamp = intent.getLongExtra("TIMESTAMP", 0);
if(app.getPrevTimestamp() == timestamp){
//前回と同じなので実行しない
}else{
//今回はなにか実行する
app.setPrevTimestamp(timestamp);
}
}
}
}
※呼び出される側はインテントをウケれるようにマニフェストを記述してください。Intentの使い方間違えてるかもしれない&そもそもこんな状況になる作り方が悪いのかわからないので誰か教えて!
(重要なことなので2回言っちゃった)
ずいぶん前に@gabuさんに相談して「消せないっすね~」的な話にはなってたのですがやっぱり気になったので記事にしました。
ss.momonga
現在Launcherアプリを作成しており、色々と調べている最中にこのサイトにたどり着きました。
この件、今更なので解決済み or どうでも良くなっているかも知れませんが。
また、私も適当な推測であり、未検証なのでどこまで正しいか分かりません。
ホームキー長押しでアプリ履歴から起動する時、RecentTaskInfoでintentそのもの履歴を取得してようなので、この例にあるアプリBで何とか消す方法は無理と思います。
アプリAでintentを作成する際にFLAG_ACTIVITY_NO_HISTORYを立てればRecentTaskInfoに載らないようになるんじゃないかと。
間接的ですが、ホームキー長押しからgetExtrasされることはなくなります。
あやね
> ss.momonga さん
情報ありがとうございます。参考にします。
特別解決はしてないのですが何とかなってるので放置しちゃってます^^;
currysita
すみません、私も同じ場所でつまづきました。
Activityに、以下のようなIntent更新用のメソッドを作成する事で、内部からIntentを更新できるようにしました。
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.d(TAG,"onNewIntent 走ったお!"); setIntent(intent); }次に、onResume内部で以下のように処理を実装しました。
@Override protected void onResume() { super.onResume(); Intent i = getIntent(); HogeHogeObject hoge = (HogeHogeObject)i.getSerializableExtra("hogehoge"); if(null != hoge){ Log.d(TAG,"hogehoge が取れたよ!"); i.removeExtra("hogehoge"); this.onNewIntent(i); return; } }これで、取りあえず対応できました。
合っているかは解りませぬ…
kkenjh
まさに同じことで悩みました。
FLAG_ACTIVITY_NO_HISTORYや、Activity自体にno_historyをセットしたりなどして
試しましたがうまくいかず、掲載されたグローバル変数でインテントのタイムスタンプを
確認する方法と、アクティビティーのランチモードをl"singleTask"にすることで、
何とか対処できました。
貴重の対処方法を掲載して頂き、本当にありがとう御座いました。
kkenjh
まさに同じことで悩んでいました。
インテントでのFLAG_ACTIVITY_NO_HISTORYやアクティビティーにnohistoryをセットしたり
したのですがうまくいかず、行き詰っていました。
掲示されたglobal変数でインテントのタイムスタンプを確認する方法で
何とか解決できました。
貴重な対処方法を掲示して頂き、本当にありがとう御座いました。