2011年12月13日火曜日

任意のタイミングでトゥームストーン状態にする。(メモリーを喰い尽くせ!)

Windows Phone Advent Calender 13日目です。

内容は

任意のタイミングでアプリをトゥームストーン状態にする!

です。


  • そもそもトゥームストーン状態とは?

アプリケーションが非アクティブ状態の時に、OSのリソースが不足すると、OSは非アクティブのアプリケーションのプロセスを強制終了してリソースを確保します。
この時の状態をトゥームストーン(Tombstoned)状態といいます。

このトゥームストーン状態になったアプリケーションがアクティブに戻るときはリソースが解放された状態から再開しなければならないため、事前に作業中の情報を保存したりしないといけません。

この辺りは、今回の内容とは少し外れるため、詳しくはこの辺りをじっくり読んでください。



  • デバッグ実行でトゥームストーンにする方法

さて、作ったアプリがトゥームストーン状態になって戻ってきたとき、ちゃんと情報が保存/復元できるかをテストしないといけないわけですが、一般的な方法としては、デバッグ時のオプションを利用する方法があります。

WindowsPhoneアプリのプロジェクトのプロパティを開くと、デバッグタブ内に「デバッグ中の非アクティブ化時に廃棄する」というチェックボックスがあります。


このチェックボックスにチェックを入れると、アプリケーションを非アクティブ化した時(例:アプリ動作中にスタートボタン押下)、毎回必ずトゥームストーン状態にしてくれます。
そのため、効率的にトゥームストーン状態からの復帰処理をデバッグすることができます。


  • ○○Taskだと、うまくいかない・・・

基本的には上記の方法でトゥームストーン状態のテストが可能ですが、それが出来ないパターンがあります。

例えば、CameraCaptureTaskをアプリ内から起動し、写真を撮影後、そのデータを取得しようとしますが、トゥームストーン状態からの復帰となるためか、うまくデータが取得できません・・・。

そのため、○○Taskを使ったアプリでトゥームストーン状態のテストをするのは困難なのです。


この件についてUX-TVでも質問してみたところ、大西さん曰く

「任意のタイミングでトゥームストーン状態にするのは難しい。」
「しばらく複数のアプリ立ち上げて待ってればなるかもしれないけど、非効率ですね。」

ということでした。


  • よろしい、ならば落としてやろう

そりゃ困ったなーということで、こっちの意図したタイミングで無理やりトゥームストーン状態に突き落す方法を考えました。

要は、OSのリソースを不足させてやればいいわけですよ。

OSのリソースって何よ?ってことですが、プロセスを殺す必要があるということは、きっとメモリーじゃないかと推測し、メモリーを可能な限り確保してリソースを喰い尽くすことにしました。

private void AllocMemory(int mib)
{
 int bytes = mib * 1024 * 1024;
 AllocatedMemories.Add(new byte[bytes]);
}

private void FullAlloc()
{
 for (; ; )
 {
  try
  {
   AllocMemory(2);
  }
  catch (OutOfMemoryException)
  {
   MessageBox.Show("メモリを食い尽くしました");
   break;
  }
 }
}


こんな感じで1MiBずつ確保する関数を作って、OOMが発生するまで2MiBずつ確保していきます。

そしてできたのが、MemoryEaterGreenです。

IS12Tの場合、デバイスメモリ362MBのうち、211MBを食い潰すことに成功しました。

この図はエミュレータの場合で、427MBのうち276MBを確保しました。


しかし、一つのアプリで確保できるメモリの制限に引っかかってしまい、非アクティブ状態のアプリをトゥームストーン状態に追いやるのに十分なメモリを確保できませんでした。

そこで、MemoryEaterRedの出番です。(Greenの色違い。機能的な差はなし)

MemoryEaterGreenでメモリを食い尽くした後、「スタートボタン」でホーム画面に戻り、
今度はMemoryEaterRedを起動し、同じく、メモリを食い尽くします。

そうすると、MemoryEaterGreenで食い尽くすときよりも、Redで食い尽くすときのほうが少し時間が掛かると思います。
このとき、裏で非アクティブ状態のアプリケーションがトゥームストーン状態になり、確保していたリソースが解放されています。

つまり、


  1. アプリを起動し、トゥームストーン状態テストしたい画面まで遷移させ、スタートボタンを押下(非アクティブ化)
  2. MemoryEaterGreenを起動し、[Allocate Full]を押下 → スタートボタンを押下(非アクティブ化)
  3. MemoryEaterRedを起動し、[Allocate Full]を押下 → 戻るボタン押下 x 3

これで、対象アプリがトゥームストーン状態から復帰するはずです。
対象アプリが復帰するとき、「再開中・・・」という画面になれば、バグ技の成功です!

もし、GreenRedでも足りないくらいメモリを積んだ端末が出たときには、BluePikachuを自分で作ってください。

  • プロジェクトファイル一式
プロジェクトファイル一式はこちらからどうぞ

2011年8月1日月曜日

IRリモコン for DSLR リリースしました

Androidアプリの「IRリモコン for PENTAX」 改め、

IRリモコン for DSLR

をリリースしました。

変更点は名前の通り、主要メーカー(Canon, Nikon, Pentax, Sony)のリモコン信号に対応しました。

開発していて気になったのは、Canonの信号到達距離がかなり短いこと。
K100Dは10m位離れても大丈夫だったのに、Canonは3m位までしか届きません。
元々、Canonのリモコンは強い信号を出しているのか、個体の問題なのかは不明です。
何か情報があれば教えてください。
あと、Sony,Nikonの信号到達距離も気になりますね…。

Nikonのみ、動作確認が出来ていなかったのですが、マーケットのコメントで無事に動いたとご報告いただきましたので、良かったです。

今は、内部設計のやり直しと、UIの刷新を検討中です。

欲しい機能や、改善してほしい機能等有りましたら、どしどしお寄せください!

2011年6月1日水曜日

IRリモコンforPENTAX アップデートしました

IRリモコンforPENTAX

Ver. 1.6の主な変更点
・例外をcatchして、落ちなくした。
・物理ボタンの音量ボタン、検索ボタン、シャッターボタンを押しても信号送信するようにした。
・信号送信出来たら、バイブでフィードバックして、分かりやすくした。

どうも、2chのk-xスレのテンプレに入れて頂いたようで、ダウンロード数が一気に伸びてました。

今後とも、バルブ対応とかして行こうと思いますんで、よろしくお願いします。


そう言えば、Nikon,Canon用コードを仕込んだテストアプリを持ってデオデオまで行ってきたんだけど、テストするまでの間に必ず、店員に「いかがですか」って声掛けられるので、なかなかテストが出来ない…。
結局Canonは上手く動いたけど、Nikonはダメだった。
ワンショットで3社分送ったのがまずかったのか、信号がまずかったのかは不明です。


とりあえず、スイッチサイエンスで マルチインターバルリモコンキット を購入したので、コイツのコードを解析して、ついでにSonyとかにも対応したいです。

でも、いろんな人がいる場所で使うことを考えると、マルチリモコンにするよりは、選択式にした方が誤作動が少なそうで良いよね〜。

2011年5月28日土曜日

SH-12Cで赤外線リモコンアプリ作成中

先日、2年使ったSH-06Aから、ガラスマのSH-12Cに乗り換えました。

SH-12Cは、IS05や006SHから対応が始まった赤外線リモコンAPIが使えるようです。
・・・ということで、早速赤外線リモコンアプリを作成してみました。

Androidの赤外線リモコンアプリはほとんど(まったく?)ないようで、Marketで検索しても出てきません。

まずは、SHARPのSH Developer Square から「SHARP SDK AddOnをダウンロードして、Eclipseに組み込みます。

最初に作ったのは、Pentaxのカメラ用リモコンでした。
自分はPentaxユーザで、SH-06Aの時はiアプリでリモコンアプリを入れていましたので、それの代わりになるよう、作ってみます。

赤外線リモコンアプリを作るには、まず赤外線の信号を解析する必要があります。
赤外線の解析については、別途ハードウェアが必要になります。
幸い手元にArduinoとリモコン受光部があったため、ちゃちゃっと繋いでスケッチ書いて、(本物のリモコンは持っていないので)iアプリのリモコン信号を解析します。
ハードウェアがない方はネットで調べれば、各機種のリモコン信号のデータが手に入ると思います。
ただし、デバッグのためにも、Arduinoとリモコン受光部はあった方が便利です。

リモコン信号のデータが解析出来たら、あとは、同じ信号が出せるよう、赤外線APIとにらめっこしながらプログラムを書いていきます。

てな感じで出来たのが、このアプリです。

IRリモコン for Pentax (AndroidMarket)

なお、まだテストはしていませんが、NikonとCanonの信号も実装したアプリも作ってみたので、ちゃんと動くのが確認出来たら、リリースしようと思います。

3社の信号を連続して送れば、マルチリモコンになるんですが、そうすると、カメラマン密集地での誤作動や、ボタンを押してからのタイムラグが気になると思うので、メーカーを選択するようにしようと思っています。

赤外線リモコンアプリの実装についても、また時間があるときに詳しく説明したいと思います。