Windows10MobileのUWP開発でVisualStudioから実行した場合と実機から実行した場合で挙動が変わる恐怖体験をした話 ~FileOpenPickerには気を付ける~

ことのはじまり

年末にUWPつくって、ストアにリリースしたわけなんですが、10Mobileに限って、実行したときの挙動がおかしい問題に遭遇しました。

その問題もおかしくて以下の条件に限っておかしい挙動をしました。

  • 端末に配置してあるアプリをタイルをタップして実行したときおかしい挙動
  • VisualStudioから実行した場合は挙動はおかしくならない
  • PCでは挙動がおかしくならない、10Mobileだけ挙動がおかしくなる
  • DebugビルドでもReleaseビルドでも挙動は同じ(DebugかReleaseかは関係がない)

そもそも10Mobileだけ、端末のアプリを実行したときだけおかしな挙動になる時点でおかしすぎて初めて遭遇したときはびっくりしました。

なにせVisualStudioから実行したときは普通の挙動になるのでデバッグもできないし、MessageDialogで値を表示したらVisualStudioから実行したときはtrue、アプリをタップして実行したときはfalseになるとか恐ろしすぎてバグか?と思うぐらいでした。

原因

原因はFileOpenPickerでした。

Windows10MobileではFileOpenPickerでPickSingleFileAsyncメソッドを実行するといったんアプリはサスペンドされ、ファイルを選択するとアプリがレジュームされるわけですがアプリがレジュームしたときに保存データから復元する処理が通っていたせいで挙動がおかしくなったというものでした。

PCの場合はPickSingleFileAsyncメソッドを呼んでもアプリはサスペンドされないので挙動は普通のままで、VisualStudioから実行時もおそらく特別なプロセスとなるためサスペンドされず、よって10Mobile端末からアプリをタップしたときに限って、おかしな挙動になることがわかりました。

PickSingleFileAndContinueすればよいのでは

もともとPhone8.1ではサスペンドを前提としたPickSingleFileAndContinueメソッドを実行していたのですが10Mobileからはこのメソッドは使えなくなっていました。

ちゃんとサスペンド通ってるのであればレジュームしても問題ないのでは

僕もそう思ったんですけどなんか挙動がおかしくなりました。というよりサスペンドは通ってるけどデータが保存されてない?

defferalのせいかも

Resumingイベントでストレージピックから帰ってきたときかどうかを判断してデータを復元するかどうか選択すればよいのでは

まあ結局この方法で解決したんですけど一筋縄ではいきませんでした。

まずストレージピッカーから帰ってきたという情報がレジューム時にあたえられないので判断ができません。

また、LaunchもActivateメソッドも実行されないのでActivationKindで判断もできません。

そこでLocalSettingにIsPickingというフラグを保存してファイルをピックします。

ファイルピックが終了したらこのフラグをoffにします。

そしてレジュームイベントでは、フラグがあるときかつフラグがOnのときのみ、データを復元しないような処理をかきます。

これでなんとかなりましたが非常に恐怖体験でした。