2013年10月31日木曜日

TextureViewのライフサイクル(予想)

ところどころ違う箇所があるかもしれません。
なので予想です。表現が違っている箇所があるかもしれません。
例えばGLにtextureの作成を依頼するところとか。

肝はsurfaceを通じてnativeのGLの描画と関連付けすることです。
関連付けたsurfaceさえあればGLの描画スレッドとやりとりできるということです。
surfaceがHandlerみたいな感じですね。

Listenerは通知です。
AvailableはTextureViewが持つsurfaceをGLに関連付けするフェーズです。
UpdatedはGLからのsurfaceの受け取り完了通知を表しています。
DestroyedはGLに対して関連付けしたsurfaceの破棄を依頼することを表しています。


start
TextureViewがaddViewされる

TextureViewのonAttachedWindow
変更:getHardwareLayerが呼ばれて

TexureViewにSurfaceTextureListenerしたmListenerが呼ばれる


mListenerのonSurfaceTextureAvailableが呼ばれる

mListenerのonSurfaceTextureAvailableでsurfaceが用意されている

追加:Runnableに入る前にメンバーとしてGLインスタンスもっとかないと色々マズイ

surfaceのtextureを作るRunnable()を実行する。引数にsurfaceが必要。

RunnableでopenGLESの初期化と設定を行う。もしかしたらUI上で初期化がいるかもしれない。

surfaceをGLとバインドする。超大事。

初期化と設定が終わったらGLにsurfaceに描画するtextureの作成を依頼する

GL側でtextureができたらmListenerのonSurfaceTextureUpdatedが呼ばれる

textureがsurfaceに表示される
end

start
AcitivtyなりFragmentなり自身がisFinishing = trueなり、isRemoving = trueになり、detachedなり。

TextureViewのonDettachedWindow

onDettachedWindow内でmListenerのonSurfaceTextureDestroyedが呼ばれる。

surfaceをクライアントか「システム※1」かどちらが破棄するかのフラグをリターンする
※1.trueならonSurfaceTextureDestroyedが終わった後にonDettachedWindowでreleaseされる

追加:メンバーとしてGLインスタンスもっていれば、ここで破棄をGLに依頼できる※2
※2.onDettachedWindowに戻る前に破棄ができる。
onDettachedWindowでmListenerとのバインドが解除される

onDettachedWindowが終了。surface及びmListenerとの関連付けが全てなくなる。
end

2013年10月30日水曜日

Looperとやり取りするMessageQueの中身が見れない

TextureViewのsurfaceの破棄のところでひたすら詰んでます。


メッセージキューの状態ってどーやって見れるんだ。。。

メッセージのキャンセルもわからないし。
ブロッキングもわからん。

代価案としては、
自前でリストをもっておいて、
postして終わったかどうかどうかisAliveとかでオブジェクトを判定して、
終わっていたらremoveとかそんな感じなのかなぁ。

Looperの終了処理もあんまり見受けられないし、作りっぱなのかなぁ。
4.3のメソッドで安全にLooperを終了するよっていうメソッドもあったけど、
4.3ベースとかありえんし。

Looperおそろしい子っ。

2013年10月28日月曜日

Viewのサイズの取得できるタイミング

TextureViewでBufferとして使うBitmapをFragmentの開始あたりで取れないかなーと思った。
Loaderまわして、CacheにBufferとなるデフォルトを作ってからTextureViewをスタートさせたかった。

しかし、Viewのサイズは取得できない。
FragmentからだとViewのサイズが確定するタイミングを取得することができない。
ログを入れたところ、全て0だった。
ライフサイクル通りですね。ViewはWindowにアタッチされた時に自身のサイズを決定します。
ActivityならOnWindowFocusChangedで取得できる。

サイズ決め打ちなら作ることはできるけど、動的に取得するならそうもいかなかった。

どうしても欲しいなら、Interfaceを使ってActivityのonWindouFocusChangdeとやり取りすればいいと思う。ActivityのOnWindowFocusChangedでActivityのinterfaceからFragmentに通知する形です。

ActivityのOnWindowFocusChangedから、Fragmentでインプリメンツしたメソッド内で、現在アタッチされているViewの階層構造をたどって、お目当てのクラスなりidなりで引っ掛ければ取得できると思う。
でも、スマートじゃないというのが私見です。がっつり結びつくのって好きじゃないんですよ。

ややこしくなりそうなので、textureviewの中でやります。

他のアプリだとloading画面って何やってるんだろうなー

2013年10月25日金曜日

Contextの違い

色々気になってwebをちらほら。

contextの違いを要旨だけ。
getApplicationContext()
・・・アプリケーションのライフサイクルに沿った値が入っている。
this(=Activity)
・・・Acitivityのライフサイクルに沿った値が入っている。
getBaseContext()
・・・contextにラップされているものを1枚はがした場合の値が入っている。


よくまとまっているサイト様

Android:引数はthisか?getApplicationContextか?ActivityとApplicationの違い
http://yuki312.blogspot.jp/2012/02/thisgetapplicationcontextactivityapplic.html


上記サイト様でdialogを例として解説があります。
dialogの引数にappのほうのcontextをつっこむと、

引用ここから
ApplicationContextでは適切なWindowTokenが得られないためエラーが発生しました。
このことから、ContextインスタンスであってもActivityContextと、ApplicationContext
には違いがあり、APIによってはエラーとなることがわかりました。
引用ここまで

なるほど。たまに消えるダイアログのあるアプリがあるのはこういう理由なのかな。

で、getBaseContext()についても解説がありました。
使わないほうがいいよとgoogleのデベロッパーさんが言ってたそうです。

Viewの傾きでActivityの傾きはあてにならない

そりゃそうですよね。
世の中2pain以上のレイアウトもあるわけでして。
どんな風にどんな形でViewをつっこんでもいいわけでして。

というわけで、じゃあどう判断するのということで。

内部でgetWidthとかgetHeightの関係でboolean isSelfPortraitでも作りましょう。
んで、if文で

if (isSelfPortrait){
  処理A
}else {
  処理B
}
とか作りましょう。

2painとか実装によっては後から変更とかあり得るので、
Activityの傾きは使わないように。

とTextureViewでActivityの傾きであれこれしてしまった体験談。

2013年10月22日火曜日

ひじょーに悔しかったので書いておく

listfragmentってあるんですよ。ええ、すごく便利なやつ。
そいつにですね、ちょっとてこずったんですよ。30分くらい。

てこずった内容なんですけどね、
arrayadapterってあるじゃないですか。
そうそう、カスタムして使うやつ。
ぱらっと目次みたいなの作ろうと思ったんですよ。
クラスもつくってぺたりとしたわけですよ。
出てこないんですよ。目次が。

おっかしーなーとログ入れてみたんですよ。
getViewが呼ばれてないんですよ。意味不明でしたね。
なんかおかしいのかなーと思って、スタックオーバーフロー眺めましたよ。
それらしいのがないわけですよ。
んなあほな。と思いますよね。

煮詰まったので、クラスごとコメントアウトして新しく作ったんですよ。
出たんですよ目次が。
意 味 が 分 か ら な い

よーく見直しました。

「コンストラクタ内部で呼んでるsuperの引数の数があってない」

いつ消したんだおれ。。。

Fragmentのバックスタックを全て破棄