こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Android Titaniumで予期せず停止

iPhone/iPad と Android のネイティブアプリを両方とも少し開発したことがあるくらいの経験ですが、Titanium によって両方に対応するアプリを作れるということを知り、さっそくインストールして簡単なアプリを作ってみました。

iOS のアプリは問題なく動作したのですが、Android アプリを実行しているときにリスト表示の上で左右フリックを繰り返すと「予期せず停止しました。やり直してください」というエラーメッセージが表示されてアプリが落ちてしまいます。

リストは上下にスクロールするものを作っていますので左右フリックは想定しているオペレーションではありませんから、反応してほしくないところですが、落ちてしまうのはちょっと困ります。

サンプルとして用意されている KitchenSink をコンパイルして Android で実行してみましたが、最初の画面に表示されるリストで左右フリックしたら同様に落ちてしまいました。

手元には Android 3.2 と 4.0 の2種類(どちらもタブレット)があるのですが、どうやら、落ちるのは Android3.2 で、Android4.0 では落ちないようです。

DDMS のログには下記のようなメッセージが記録されていました。
11-29 11:37:32.429: E/TiApplication(7894): (main) [4261,19410] Sending event: exception on thread: main msg:java.lang.IllegalArgumentException: pointerIndex out of range; Titanium 2.1.4,2012/11/09 12:47,51f2c64
11-29 11:37:32.429: E/TiApplication(7894): java.lang.IllegalArgumentException: pointerIndex out of range
11-29 11:37:32.429: E/TiApplication(7894): at android.view.MotionEvent.nativeGetAxisValue(Native Method)
11-29 11:37:32.429: E/TiApplication(7894): at android.view.MotionEvent.getY(MotionEvent.java:1564)
11-29 11:37:32.429: E/TiApplication(7894): at android.widget.AbsListView.onTouchEvent(AbsListView.java:2842)
11-29 11:37:32.429: E/TiApplication(7894): at android.widget.ListView.onTouchEvent(ListView.java:3591)

この辺りをたよりにググってみたところ、同じエラーメッセージ「pointerIndex out of range」に関する記事がありました。

https://groups.google.com/forum/#!msg/android-sdk-japan/JVlYcLbUSXM/NmDTodwPdP4J
この記事によると Android のソースの方に問題があるような雰囲気を感じました。

http://stackoverflow.com/questions/12368451/android-scrollview-ontouchlistener-exception
この記事では、event.getPointerCount() あたりに問題がありそうな感じがします。

どちらもマルチタップに関係する問題のようですが、Android 内部の問題のように見えますので、Titanium アプリから回避する方法はわかりませんでした。

現在作っているアプリではマルチタップは当面必要ないので、マルチタップが反応しないようにすれば良いかと思い、下記のようなことを試しましたが、改善しませんでした。

・Window や List や ListRow に twofingertap イベントを設定して何も行わない
・ListRow に removeEventListener('twofingertap')
(JavaScript や Titanium がよくわかっていないので間違っているかもしれません)

他に何か回避方法や、アドバイス等ありましたら、いただけるとありがたいです。
よろしくお願いします。

投稿日時 - 2012-11-29 11:59:05

QNo.7821240

困ってます

質問者が選んだベストアンサー

そこからのリンクでたどり着いたところにありましたが、以下は試されましたか。
タッチされたポイント情報を調べるのに、getPointerCountだのメソッドを使わずに、event.getActionから直接タップしたポイントの位置情報などを取り出すようにすればいいみたいです。

int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;

if(actionCode == MotionEvent.ACTION_POINTER_UP || action == MotionEvent.ACTION_UP) {
int which = action >> MotionEvent.ACTION_POINTER_ID_SHIFT;
int id = event.getPointerId(which);
float x = event.getX(id);
float y = event.getY(id);

確認していないのでこれで動くのかわかりませんが……。

投稿日時 - 2012-11-29 13:56:09

お礼

さっそくの回答ありがとうございます!

おっしゃることは分かりますし、そのような修正を行えれば良いのですが、なにぶんにも Titanium というフレームワークを使っている関係で、Java で書くことができないのです。

このフレームワークでは JavaScript を基本に画面を組み立ててアプリを作るということになっており、おおよそ下記のような感じになります。(ソースからのコピペではないので実際に動くものではありません)

//ウインドウを作る
var win = Ti.UI.createWindow({
backgroundColor : 'white',
});

//リストを作る
var resultlist = Ti.UI.createTableView();

//行を作成して、登録
for (var i = 0; i < json.result.length; i++) {
var row = Ti.UI.createTableViewRow({
title:'',
height: '60',
});

var rowname = Titanium.UI.createLabel({
text : json.result[i].name,
color : '#000',
top : 5,
left : '1%',
width : '49%',
height : 'auto'
});

row.add(rowname);
tabledata.push(row);
}

//テーブルにデータをセット
resultlist.data = tabledata;
resultlist.addEventListener('click', function(e) {
Titanium.UI.createAlertDialog({
title: 'メッセージ',
message: '選択されました',
buttonNames: ['OK']
}).show();
});

・・・という感じですので、ご指摘のような修正を入れることはできないのではないかと思います。そこで Titanimum および JavaScript の範囲で回避できる方法はないものだろうかと探しております。せっかく回答をいただいたのに申し訳ありません。

投稿日時 - 2012-11-30 09:06:59

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)

あなたにオススメの質問