問題が発覚してからほぼ丸一日SampleのソースコードとSDKのソースコードをにらめっこしていた。
色々と確定した要素が一晩経ってから判明したことは、どうも描画が行われなくなるタイミングががロック画面が生成されたタイミングで表示されなくなるということが確定要素として分かった。
Android 5.xまではロック画面の生成タイミングが若干不安定だったのか、Daydreamの時にだけすこし挙動が異なっていたのかはわからないが、Android 6.0 からはロックまでのタイミングと、スリープまでのタイミングの扱いが今までと変わっているということのようだ。(まだ混乱してる感じが強く日本語になってない(笑))
ちょっと言い方を変えると、Daydreamの表示されている意味合いが変わったのかともとれる。5.xまではDaydreamの表示が行われ、スリープのタイミングまでなにも行動は起こされなかったか、またはロック画面の生成が不安定だったのかもしれない。
Daydreamを動作直後に話を限定するともう少し具体的になる。
6.0ではDaydreamの表示が行われたタイミングでロック画面とスリープ画面のカウントダウンが始まり、ロック画面までの時間が来た時点でロック画面が生成され、表示上のWindowレイヤーが変更されている。
ただし、この状態で画面スリープまでの時間が経過していなければまだ表示は行われている。
逆に先に画面スリープの時間がロック時間よりも短くても画面は表示されたままとなる。
その後、画面スリープまでの時間が経過してもDaydreamの表示は行われたままとなる。
インタラクティブモードではないDaydreamの場合は、この状態で画面タッチなどを行いDaydreamが終了するとロック画面の時間が経過していなくてもスリープまでの時間が経過していればロック画面が表示される。
おそらく仕様としてその辺が整理されたのかもしれない。
挙動も納得の行く動作結果になっていると感じます。
さて、ここまで行くまでにソースを色々と確認していました。
標準のDaydreamとして時計がありますが、時計の実装方法はとてもシンプルに行われていて、Daydream独自のコードはほとんどありません。
実際の処理の中身はカスタムビューとして定義されています。とくにSurfaceViewが使われているわけでもなく、一般的なView要素として表示が行われているため、Android的にはものすごくスマートな実装方法になっています。
またもう一つのColorsは、SurfaceViewに近いおそらくGLSurfaceViewで実装され、描画もほとんどView側で処理され最終的にはOpenGLに表示は委ねられている形になっています。
どちらも個人的に一般的だと思っていたSurfaceViewでの実装ではなく、なんというかマニアックな実装方法だと感じています。
ここでソースコードを忘れて結果だけとらえれば「SurfaceViewがダメなんじゃね?」的な発想になりますが、この時点ではまだSurfaceViewを悪く考えることができませんでした(笑)
結果、シンプルなDaydreamのソースを作り、そのあとlayoutファイルでTextViewとSurfaceViewの要素のものを画面に表示させていろいろと試したところ、TextViewの内容はいつでもどのタイミングでもしっかりと表示され、同時に表示されているSurfaceViewはロック画面が生成されていると思われるタイミングで描画しなくなっているという結果が確定しました。
ではSurfaceViewがダメならいったいどうすれば良いのだろうと言う事に本題が(ようやく)移行します。もうこの時点でほぼ丸一日、どんだけどんくさいんだよ…。
さて、選択肢は色々ありますね? あるのかな?
アプリをできるだけ手軽に修正したいというのが前提になります。
OpenGL化するには色々と面倒なことになりそうです。
ほかは??
と、いろいろ見ていましたが前から気になっていたSurfaceViewの下のTextureViewというものが使えるのかな?という期待で検索してみました。
結果としてはほぼ代用できそうです。
そのままの状態でCanvasが扱えるのが一番の利点でしょうか。
実際にSurfaceViewのものを強引にTextureViewに置き換えて実行してみます。
ちゃんとまともに動作するのがようやく確認できました。
例外処理の発生タイミングがわからないのと、API14以降というハードルが残っていますが、API14以降というのはそもそもDaydreamがAndroid 4.2(Jelly Bean MR1)の17なので問題はありません。古いバージョンに対応しているのはちょっと対応に悩みそうです。
0 件のコメント:
コメントを投稿