2010年07月

2010年07月31日

WindowsPhone:位置情報を利用する

 Code Samples for Windows Phoneを少しずつ試していくシリーズ。今回は位置情報を利用するサンプルについて紹介しようと思います。

位置情報を取得する方法



 位置情報を取得する方法として、

 ・正確性には欠けるが消費電力の少ないWi-Fiなどのネットワークの情報を利用する方法

 ・GPSからのよりパワーを消費するが精度の高い情報を取得できる補法

 があるようです。
 どちらを選択するかはアプリケーション製作者としては悩ましい問題ですね。

 確かに携帯デバイスで位置情報を利用するアプリを利用した場合に激しくバッテリーを消費したのを体験したことがあります。

プログラムコード解説



 Location Programming Best Practices for Windows Phoneのサンプルコードは

 GeoCoordinateWatcher watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.Low);


 となっていますが、GeoPositionAccuracyのプロパティはDefaultとHighの2種類のようです。

 Lowに相当するのがDefaultで精度の高い位置情報が必要な場合はHighを利用するように変更されたのかもしれません。

 MovementThresholdプロパティは移動を検知する閾値を設定します。あまりに過敏に反応しないようにということなのかな。

 StatusChangedイベントとPositionChangedイベントは、それぞれ位置情報検知の状態が変更になった場合と位置が変更になった場合に発生するイベントです。

 StatusについてはGeoPositionStatusに定義されている種類の状態に遷移します。

 

エミュレーターだと位置情報が取れない?



 サンプルを実行した感じだとエミュレーターで位置情報を仮想的に用意することはできていないようです。

 残念。

WindowsPhone:ガーベージコレクションについて

 WindowsPhone7のガーベージコレクション(GC)について言及されたサイトの紹介

 Windows Phone 7 App Development: When does the GC run

screen


GCが実行されるケース



 日本語のコメントは自分の拙い英語力をもとに読み解いた結果なので無視するか、訂正してください。

1.After some significant allocation:

When an application tries to allocate managed memory the allocator first checks a counter that indicates the number of bytes of managed data allocated since the last GC. If this counter crosses a threshold (which is changeable and set to 1MB currently) then GC is fired (and the counter is obviously reset).
The basic idea is that there has been significant allocation since the last GC and hence do it again.


 大量のメモリを割り当てた後という意味ですかね。
 前回のGCから一定量の割り当てがあった際にGCが実行されるようです。

2.Resource allocation failure

If some internal native allocation fails, like loadlibrary fails or JIT buffer allocation fails due to out-of-memory condition then GC is started to free up some memory and the allocation is re-attempted (only 1 re-attempt)


 リソースの割り当てに失敗したとき。

 ライブラリの読み込みのような、なんらかのネイティブな割り当てに失敗したとき、またはJITバッファー割り当てに失敗したとき。

 JITバッファーってなんでしょうね?

3.User code can trigger GC

Using the managed API System.GC.Collect(), user code can force a GC


 ユーザーによるGC処理呼び出しが行われた場合。


4.Sharing server initiated

One of the new features in the WP7 CLR is the sharing server (see my post http://blogs.msdn.com/b/abhinaba/archive/2010/04/28/we-believe-in-sharing.aspx for details). In WP7 there is a central server coordinating all the managed processes. If this sharing server is notified of low memory condition, it starts GC in all the managed processes in the system.
 

 Sharing serverの仕組みは上記にあるURLでなされていますが、OSのカーネル(のような役割のもの)がアプリケーションのGCを呼び出すことがあるということのようです。
 デバイス全体のメモリ管理の仕組みなのでしょうね。

 サーバーというところからも、サーバー/クライアントモデルなのかな。

GCが実行されないケース



1.GC is not run on some timer. So if a process is not allocating any memory and there is no low-memory situation then GC will never be fired irrespective of how long the application is running

プロセスがメモリを割り当てず、全体のメモリが少ない状態になっていないならGCは実行されることはありません。

 資源は大切にね!! ということですね。

2.The phone is never woken up by the CLR to run GC. GC is always in response to an active request OR allocation failure OR low memory notification.


 この辺が特にわからなかったのですが、GCによってphoneが起こされることがない=休止状態ではGCは走らないということでしょうかね。
 後半の文は「GCは常にアクティブな要求または割り当て失敗、メモリ低下の通知に従って実行されます」ですかね。

 どなたかフォローよろしく…。

3.In the same lines there is no GC thread or background GC on WP7


 同じライン(???)にGCスレッドまたはバックグラウンドGCが無い場合。これも意味不明でした。
 こういう短い短文は難しい。


 …とまぁ、英語力が及ばない限りですが、興味がある方は原文をお読みください。

2010年07月29日

WindowsPhone:発売予定だったり公開されている書籍情報

 下のサイトでWindowsPhone7関連の書籍が色々紹介されています。
 (初の韓国語サイトへのリンク!!)

 書籍紹介サイトへのリンク(韓国語:文字化けしてしまった)

 上記サイトを見るとWindowsPhone7関連の書籍も色々準備されているようです。
 中にはPDFでプレビュー版を見れるものもありますね。
 前にも紹介しましたがこちらはソースコードもDLできるようになってました。

 概要の感じだと

 Beginning Windows Phone 7 Development
 Pro Windows Phone 7 Development

 が見たいなぁ。


 ちなみに最近拙い英語力でWindowsPhoneの海外サイトを一生懸命読んでいるんですが、

 「MSDNライブラリによく出る英単語 100選」

 は、あーっ見た見たこの単語!! という感じで自分のレベルにちょうど良いです。

WindowsPhone:初XNA

 Silverlightで作成するのに向いていること、XNA向きなことを判断するために軽く触ってみようかなと。

 すごく簡単だけど初XNAアプリ!!

 キャプチャ


 目覚ましアプリっぽいのを作ろうとSilverlightとXNAでそれっぽいものを作り始めて、WP7がバックグラウンドでのアプリ動作を許可してないことに気が付きました…

 常にフォアグラウンドで動かす必要がある目覚ましアプリって需要あります?w

WindowsPhone:新着情報(未読含む)

 開発者向けのためになりそうなページを紹介

 Microsoft XAML Toolkit CTP - July 2010

 まだCTP版だがXAMLをLINQに通したりできるもよう。
 FxCopってのはコーディングルールをチェックしてくれるのかな。

 screen1

 (クリックで拡大)


 Windows Phone 7 ? The First Fart Application

 コードとかチュートリアル付のエントリはありがたいですね。


 Reactive Framework (Rx) Wiki
 
 ReactiveFrameworkのコードサンプルがいっぱい。
 このページでLINQのサンプルいっぱいも知りました。


 Loading, iterating, and saving photos with WP7

 これもコード付きサンプル。

 なかなか情報が増えてきましたねぇ。
 

2010年07月28日

WindowsPhone:Reactive Extensionsを試してみる

 Code Samples for Windows Phoneのサンプル紹介も残り少なくなってきました。

 今回はReactive Extensions Location Service Emulation Sampleの解説をしてみようと思います。

 (開発ツールのバージョンはbetaです)

Reactive Extensionsとは



 Reactive Extentions(以下Rx)は非同期処理をLINQライクな構文で記述することができるようになるモジュールでMSDNのDevLabsで公開されています。

 非同期処理の書き方がシンプルになりそうなので注目はしていたのですが動かせる環境が限定的だったこともあり、ちゃんと触ったことはなかったのですが、

 WindowsPhone7では標準で備わっている

 ということなので、そろそろ時期だろうということで手を出してみようと思います。

サンプルは例外出ちゃった



 自分の環境だとサンプルを動かすと以下のように例外が出てしまうので、深追いせずにRxを利用している部分だけ紹介。

 screen1

 (クリックで拡大表示)

 アプリケーションは現在の位置情報を定期的に取得するサンプルで、emulationをTrueにした場合固定データを用いてアプリを動作させるというものですね。

 位置情報などが利用できないエミュレーターで動作を見るときの参考になります。

Rxを利用する



 先ほども書きましたがWindowspPhone7は標準でRxが利用可能なので参照を追加すればそのまま利用可能です。

 screen2


 Microsoft.Phone.Reactiveを参照に追加。すべてのケースで必要なわけではないですがSystem.Observableも追加しておきます。

 今回のサンプルでRxを利用している箇所は以下、

screen4

 (クリックで拡大)

 一番簡単な場所を選んでみたが、同時に一番わざわざRxじゃなくてもいいようなコードな気もする。
 とりあえず仕組みを知ることに集中しよう。

 EmulateStatusEvents()は返り値がIEnumerableとなっている。定期的にGeoPositionStatusChangedEventArgs(位置情報の状態が変わったイベント)を発生させるモックだ。
 それをToObservable()メソッドでObserve(監視)可能なクラスに変更する。

 varを用いているがstatusEventsToObservableはIObservable<GeoPositionStatusChangedEventArgs>型だ。

 それをLINQっぽく取り出して、

 statusFromEventArgs.Subscribe(status => InvokeStatusChanged(status));

 Subscribe(購読)して処理する。

 平たく言ってしまえばwatcher.StatusChangedイベントにハンドらを設置した際の動作をエミュレートしているのだ。

 このレベルだと普通にデリゲートしたほうが簡単になりそうだけど、Rxだと他にも色々な処理、判定、フィルタリングをLINQライクに加えることができるので、もうちょっと複雑なケースではRxの方が簡便なコードになる(んだと思うけど、まだまだ私には経験が足りない)。

 LINQとRxはみっちり修行しないと!!

 

2010年07月27日

WindowsPhone:機体の向きを検知する(縦向き? 横向き?)

 VisualStudio2010 Express for WindowsPhoneのbetaでデフォルトのアプリケーションは向きが縦で固定されています(開発環境はbeta)。

 それはPhoneApplicationPageタグで

 SupportedOrientations="Portrait"

 と指定されているためで、
 これを横向きにした際に検知してレイアウトを変更するには、

 SupportedOrientations="PortraitOrLandscape"

 と縦横どちらもサポートするように指定します。

 あとは、

 OrientationChangedにハンドラーをセットしてあげればOK。
 サンプルコードは以下、


void MainPage_Loaded(object sender, RoutedEventArgs e)
{
this.OrientationChanged += new EventHandler(MainPage_OrientationChanged);
}

void MainPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("OrientationChanged = " + e.Orientation);
}



 ですが、上記のようにただ横向きにすると、

 こうなっているのが…
 003



 こうなってしまいます。
004



 レイアウトをあわせて変更する必要がありそうですね。

WindowsPhone:フレームレートを表示する方法

 WindowsPhone7アプリでフレームレートを表示する方法(現在のSDKバージョンはベータ)。

 元ネタは以下、

 Frame rate counters in Windows Phone

 001


 こんな感じで各種情報を表示してくれます。



 002

 (クリックで多少拡大)

 実際に表示しているサイズはこのくらい。
 エミュレーターの50%サイズだとちょっと見難いので拡大すると吉。
 

表示方法



 注意するのはシステムトレイを表示すると隠れてしまうのでMain.Page.xamで

 shell:SystemTray.IsVisible="False"

 としてしまうか、プログラム上でトレイを消すこと。

 あとは、

 
Application.Current.Host.Settings.EnableFrameRateCounter = true;


 で表示されるはずです。各項目の説明は上記元ネタサイトで。

 フレームレートを表示するにはDirectX10以上に対応したグラフィックカードが必要とか。

 実機でも表示できると開発に便利そうですね。

2010年07月26日

WindowsPhone:Debug用のROMイメージを変更する(その2)

 MicroSoftの社員の方は全員WindowsPhone7をもらえたり、世界中のデベロッパ(評価者)にWindowsPhone7のプレビュー版が送られたりと世間では実機を手にしてくれる方が出てきましたね。

 うらやましがることなかれ!!
 我々にはエミュレーターがある!!!

 screen


 …IE使えるね。


 以前にCTP版のエミュレータを(起動速度と引き換えに)実機っぽくする手段を紹介しました。

 この方法はbetaで使えなくなったのですが、betaでもちょっとそれっぽく使える方法が紹介されてました。
 んー、これMicrosoft的には不許可だよねたぶん。

 アンロック版エミュレーター

 Office(っぽい)のも見れます!!
 screen2


 Mapだ(BingMapですかね)
 screen3


 さぁ、みんなで実機気分!!

 …さすがに無理ですね。

2010年07月25日

Silverlight:Accordionコントロールを利用する(その3)

 久しぶりのAccordionコントロールの進捗報告。

 FxUGの全国ツアー、Hokuriku.NET vol4、TechEdのライトニングトーク作成(落選しちゃいましたけど…)と立て続けにスライド作成が続いていたので、今週末は久々に腰を据えてプログラミング。

 Accordionコントロールのデモはこちら

 過去の記事:その1その2

 前回からあまり変わってないように見えますが、前回まではSilverlightでデータを生成してAccordionを表示していましたが、今回はサーバーサイドのPHPと通信してデータを表示するようにしてあります。

 今回はこの辺の「サーバーサイド」も絡めて紹介します。

 ちなみにローカルの開発環境は

 OS:Windows7
 サーバー:Apache2
 プログラム言語:PHP5
 データベース:MySQL5

 のWAMP構成です。
 (別に閉じたネットワーク上にLinuxサーバーがありますが話が長くなるのでパス)

CakePHPフレームワーク



 サーバー側のPHPですが、CakePHPフレームワークを利用します。
 今後規模を拡大してサイト化したいという展望のためにフレームワークを導入したのですが、O/Rマッピング、キャッシュ、テストがはじめやすいなどのメリットと、CakePHPの導入の容易さもあいまって非常に利便性が高いフレームワークです。


SimpleTest



 CakePHPでのユニットテストはSimpleTestを用います。
 サイトからDLしたファイルをCakePHPのvendorsディレクトリに配置するだけで最初の準備は完了です。

 screen1

 (クリックで拡大)

 CakePHP1.2からユニットテストが非常に便利になって、

 ・テスト実行時は本番環境と別のテスト用DBを利用してテストを行う
 ・fixture機能で自動的にテスト用ダミーデータを生成する

 という本番データにやさしい機能がついています。
 テスト用DBはdatabase.phpで$testを指定するか、指定が無い場合は自動でDBを生成してテストを実行します。

 テストについてはこのページ前後の記事を参考にしてください。
 それ以外についても上記サイトで調べると詳細を得ることができます。

 fixtureの設定を間違えるとダミーデータが入らない場合があるので、その場合MySQLのクエリログを吐き出すようにしておくと便利です。でなくてもクエリログの出し方を知っておくと便利。(もちろん本番環境ではログはオフで)

 MySQLのクエリログを取得する方法(Windowsの場合my.iniですね)

DebugKit



 CakePHPで開発する場合DebugKitをインストールしていると非常に便利です。
 Viewに渡されたデータ、実行されたSQLクエリ、セッションデーター等々をvar_dumpなどを使わずに確認することができます。

 screen2

 (クリックで拡大)

キャッシュを利用



 リアルタイム性の無いデータの場合、毎回データベースに問い合わせるのではなくキャッシュを利用してデータベースへの問い合わせ無にデータを返すことで負荷を軽減できることがあります。

 CakePHP1.2からはファイルやメモリを使ったファイルキャッシュがサポートされ(メモリはmemcach等のインストールが必要ですが)たので非常に簡単にキャッシュを利用することができます。

 実際にキャッシュを利用している部分を抜粋。

Cache::set(array('duration' => '+360 seconds'));
if( ($return_data = Cache::read('getAllHeaderInfo-index') ) === false ){

$condition = array('order_number != 0');
$fields = array('name', 'order_number', 'url', 'description', 'eng_name');

$return_data = $this->findAll($condition, $fields);

Cache::set(array('duration' => '+360 seconds'));
Cache::write('getAllHeaderInfo-index' , $return_data);
}

return $return_data;


 一度データを取得したら6分間はファイルとして保存されたデータを返します。逆にデータが変更されたとしても6分間は以前に取得したデータを返すということですね。

 キャッシュが利用されているかどうかはDebugKitを利用すると簡単に確認できます。下が上記画像のページでキャッシュが効いている場合のログです。

 screen3


 個人的に意見が分かれるところではありますが、自分はモデルの中でキャッシュを利用するコードを書きます。
 役割的にはコントーローラーで書く方が良いかもしれませんね。


ようやくSilverlightの出番だ!!

 

 開発環境でSilverlightとサーバーサイドとの通信アプリを作成して最初に引っかかるのはセキュリティエラーですね。

 System.Security.SecurityException: セキュリティ エラーです。

 こんなメッセージが出ましたら、あわてずさわがず、clientaccesspolicy.xmlを設置してさくっと次へ進みましょう。

 セキュリティエラーをクリアしたらサーバーからデータを取得できるようになります。

 今回の利用データ(xml形式)

 上記リンク先のようなデータを受け取った後の処理が以下です。
 (一部抜粋、大体の流れをイメージしてください)

// XMLとして扱うためにパースする
XElement xml = XElement.Parse(e.Result);

var header_list = from tmp_header in xml.Descendants("header")
orderby (int)tmp_header.Element("order")
select tmp_header;

var collection = new ObservableCollection();

foreach (var header in header_list)
{
var content_list = from tmp_content in header.Descendants("content")
orderby (int)tmp_content.Element("content_order")
select tmp_content;

var contenst = new ObservableCollection();

foreach (var content in content_list)
{
contenst.Add(
new AccordionContentItemData() {
content_title = (string)content.Element("content_name"),
content_url = (string)content.Element("content_url")
}
);
}

collection.Add(
new AccordionViewItemData() {
header = (string)header.Element("name"),
title = (string)header.Element("name"),
contents = contenst,
num = (string)header.Element("order")
}
);
}

var request_event = new SideNaviDataRequestEvent();
request_event.collection = collection;

// dispatch
this.completed(this, request_event);


 (ソースコードをうまく表示する方法あるんですかね。
 はてなダイアリーだと素直に整形されて表示されるんですが…)

 LINQを2回に分けて実行していますが、凄腕C#プログラマーなら一発で処理しちゃうんですかねぇ。
 まだまだLINQを使ってうまく書けるレベルではありません。

 最後の

 this.completed(this, request_event);

 はObserverパターン(C#的にはデリゲート)で別クラスに通知します。

  public delegate void downloadComplete(object request, SideNaviDataRequestEvent e);
public event downloadComplete completed;


 コードがAccordionのコントロールに依存しているのも今後の改善の課題ですね。

 なんだか、PHPの解説が多くなった気がしますが、なんとなく完成が見えてきた気がします。

coelacanth_blog at 22:49SilverlightC# この記事をクリップ!
Profile

シーラカンス

Recent Comments
QRコード
QRコード
livedoor Readerに登録
RSS
livedoor Blog(ブログ)