2012年11月15日木曜日

TitaniumでAndroidアプリを作ってる際の、クラッシュ原因

  • このエントリーをはてなブックマークに追加

Titaniumでアプリ開発を行っている際に問題となるのが、Android。
TitaniumではAndroidは冷遇されているというか、なんか微妙に使えない機能が多い。
なのでiOSベースで開発がほぼ完了した段階でAndroidのデバッグをやると、
見た目がずれているどころではなく、下手したら起動すらしないでクラッシュする。
ということで今回は自分の中でクラッシュやエラーが出てきたところを整理する。

windowのfocusイベント(tabに直結してるwindow)

Location: [284,15 ti:/window.js
Message: Uncaught TypeError: Object [object ActivityWindow] has no method 'on'
Source: this.window.on("open", function(){

tabに直結してるwindowでfocusイベントを取得し、
そのときにdatabaseの中にデータが存在してるかで処理を分岐させようとしたところ、
上記のようなエラーが出てしまった。
これは調べてみると意外と有名なバグ?であり、方法としては何種類か解決方法があるらしい。
ただアプリの作り方によってしまうのかもしれないが、下記の方法はNGだった。

win.addEventListener("focus",function(e){
  setTimeout(function(){
    //focusした時に行いたい処理
  },300);
});
で、どうやって解決したかというとtabGroupのfocusイベントを利用するという方法をとった。
■hogeWindow.js
win.addEventListener("hogeFocused",function(e){
  focusfired();
});

function focusfired(){
  alert("test");
}

■ApplicationTabGroup.js
var tabGroup = Ti.UI.createTabGroup();
//tabをどんどん追加していく処理(省略)
tabGroup.addEventListener("focus",function(e){
  var tabWin = tabGroup.activeTab.window;
  if(e.index == 2){
    tabWin.fireEvent("hogeFocused",e);
  }
});
hogeWindow内で作ったwindowに対してまずは適当なイベントを付与してあげ、
tabGroupをクリック(focus)した際に何番目のタブが押されたかを取得し、
もしhogeWindowを内包しているtabであったら、そのタブの中のイベントを発火してあげるという感じ。
ちょっとややこしいけど、これで変なエラーが出なくなった。

TableViewSectionのheaderViewによるエラー
tableViewSectionを使うことによって、各データを1区切りにまとめる事ができ、
iPhoneで見た際にスクロールするとsection毎に表示?というかsectionが上に残ったまま表示される。
さらに下記のような感じで作ってあげればカスタムした見た目にする事が出来る。

var sectionHeader = Ti.UI.createView();

sectionHeader.add(Ti.UI.createLabel({
  text:"カスタム",
  backgroundImage:"/images/custombg.png",
  height:80
}));

var section = Ti.UI.createTableViewSection({
  headerView:sectionHeader
});

section.add(Ti.UI.createTableViewRow({
  title:"row data"
});

var tbl = Ti.UI.createTableView({
  data:section
});

win.add(tbl);
TableViewSectionを作る際にheaderViewとしてViewを指定してあげるとカスタムなsectionが作成出来る。
(※後でsection.headerView = sectionHeaderとやっても反映されない)

もちろんAndroidでも同じようにカスタムなsectionを作成する事が出来るが、
iphoneみたいに残ったまま表示されるという事がない。

さらにカスタムなTableViewSectionを使うことによって、
タブを切り替えた際に予期せず中止しましたとクラッシュしてしまう。
(絶対にそうなるのかはわからないが、自分が作ってるアプリではheaderViewを使用しなかったら出なかった。)

なのでこれを解決するにはAndroidの場合だけ、sectionでheaderViewを使わないか、
そもそもsectionすら使わずに全部tableRowだけで構成してしまってもよいのではないかと思う。
(多分tableRowはいくらカスタムしてもクラッシュしないと思うので。)



上記の2点にすごく悩まされ、解決するのに延べ7日ぐらい費やしてしまった。。。
tabに直結してるwindowでfocusイベントが使えないとなると意味がないし、
buttonクリックで生成されるwindowとかだったらfocusイベントは必要なくなるわけで。

それにまさかtableViewSectionのheaderViewにこんなバグ?があるとは思わないわけで。

とりあえず今回はすごく大変だった。

Adsense