2010年12月30日木曜日

HTML5で作られた画像編集サービス

ざっと検索したら出てきました。
  1. Aviary (Tech Crunchの紹介文)
  2. Cloud Canvas (Tech Crunchの紹介文)
  3. Dark Room

Flashもびっくりのリッチなインターフェースみたい。
FlexとかSilverlightはどうなるのかなあ。
JavaScript使ったサービスが多くなってゆるやかに衰退していくのかな。

2010年12月29日水曜日

【Code Kata 翻訳 その1】スーパーマーケットの価格設定

Code Kataの翻訳をして行こうと思います
前の記事で紹介したCode Kataですが、(勿論)英語で書かれています。やってみようにも問題が分からずやる気を削がれるので、まずは翻訳してみようと思い立ちました。
1つの記事で、1つのKataを翻訳していきます。

間違いがあったらご指摘ください
久しぶりの翻訳なので、認識違いがあるかもしれません。
ご指摘よろしくお願いいたします。

それでは、「壱の型」を翻訳します。

Code Kata One - スーパーマーケットの価格設定
原文はCode Kata One - Supermarket Pricingです。

この型はDFW Practioners(注 これかな?)のミーティングでの ある議論の中で出てきました。スーパーマーケットの商品に価格を設定すること…一見単純そうに見える問題です。
スーパーマーケットにあるいくつかの商品は単純な価格設定がされています。例えば豆なら0.65ドル、などです。しかし、複雑な価格設定の商品もあります。例えば…
  • 3つで1ドル。(では、4つや5つ買った場合はどうなる?)
  • 1ポンドで1.99ドル。(では、4オンス分(= 1/4ポンド分)買ったらどうなる?)
  • 2つ買うと1つはタダになる(では、3つ買ったらどうなる?)

この型ではコーディングは必要ありません。この練習問題の目的は、お金と価格を表す様々なモデルについて試行することです。このモデルはこれらの(そして他の)価格体系を扱うのに十分柔軟な形です。また同時に、一般的によく使われています(精算時、在庫管理時、受注時、などなど)

以下の事柄について考えてみてください。
  • 端数のお金は存在するのか?
  • (やるとするならば)いつ価格の丸め込みをするのか?
  • どのようにすれば価格決定の監査証跡を保持できるのか?(そもそも保持する必要があるのか?)
  • コストと価格は同じものか?
  • ある棚に100個の缶詰があり、それらが「2つ買えば1つタダ」という価格設定ならば、どのようにして在庫を評価するのか?

この型は小さい型ですが、注意が必要です。いくつかの問題は思ったよりも複雑です。主な選択肢を検討するのに2,3週間くらいはかけてもいいかもしれません。

目的
この型の目的は、モデル化の試行をゆるい形で練習することにあります。価格設定のパターンをできるだけたくさん探してください。そして、それぞれの長所と短所について考えてみてください。また、これらのモデルを検討するのに最良のテクニックはなんでしょうか?それらのモデルを記録・保持するのに最良のテクニックは?どうすればそのモデルが合理的であることを確認できますか?

2010年12月28日火曜日

コーディングの練習のために その1

書籍を読んでいたら、役に立ちそうなサイトが書いてありました
情熱プログラマー-ソフトウェア開発者の幸せな生き方という本を読んでいたら、役に立ちそうなサイトが書いてありました。
  1. TopCoder
  2. Code Kata


以下、ほぼ書籍の丸写しですが、概要です。
TopCoder
プログラミングコンテストのサイトで、参加者登録をするとプログラミングコンテストに参加できる。
また、多数の練習問題も用意されている。

Code Kata
Kata…武道の「型」。
プログラミングの具体的なプロセスや思考プロセスについての、21通りのKataが用意されている。

2010年11月30日火曜日

apacheの.confのRewriteRuleを通すとなぜか%3とかが消えてしまう

ちょっとタイトルの意味が分からない
結局はとても初歩なんですが…。
どういうコトかというと。
apacheの設定ファイル(http.confなど)のRewriteRuleディレクティブにて、以下のような記述があったとします(URLは全部アテです)。
RewriteCond %{HTTP_USER_AGENT} IE的な何か
RewriteRule ^/(.*)$ http://example.com/redirect/http%3A//example.co.jp/ [R=302,L]

「IE的な何か」のユーザーエージェントでの全てのリクエストを「http://example.com/redirect/http%3A//example.co.jp/」にhttp status code 302でリダイレクトさせる、という記述です(のはず)。
で、最終的には 内部ロジックで「%3A」が「:」に解釈されて、http://example.co.jp/ にリダイレクトさせたいはずです。URL的には。

キモはhttp%3A//example.co.jp/となっている部分です。
http://example.com/redirect/ のエントリポイントの仕様により、「:」が「%3A」にURLエンコードされているところです。

実際に「IE的な何か」のUAでリクエストを実行すると、
  1. http://example.com/redirect/httpA//example.co.jp/みたいな形でリダイレクトされる
  2. httpA//example.co.jp/にリダイレクト
  3. 「httpA」だと、なんだそれ?とブラウザに怒られる

となってしまいました。
1.の時点で「%3」が消えてる!

なぜか
「%3」や「%1」がRewriteRuleで使われる特殊な記法だからです。
勉強不足なんで曖昧ですが、RewriteCondの後方参照として、「%n」このような記法があります。
mod_rewriteで動的ページを静的ページっぽいURLにする(Freak)にてこの辺りの解説がされています。
RewriteRuleで「%n」という文字列は避けた方がよさそうです。

「%」をエスケープしたらいいんじゃね?
「%n」が使えないなら「%」をエスケープしたら、「%n」の「%」は正しく認識されるのでは?
と思ってapacheの設定ファイルを変えてみます。
RewriteCond %{HTTP_USER_AGENT} IE的な何か
RewriteRule ^/(.*)$ http://example.com/redirect/http\%3A//example.co.jp/ [R=302,L]


で、再度「IE的な何か」のUAでリクエストを実行すると、
  1. http://example.com/redirect/http%253A//example.co.jp/みたいな形でリダイレクトされる
  2. http%253A//example.co.jp/にリダイレクト
  3. 「http%253A」だと、なんだそれ?とブラウザに怒られる

となってしまいました。
「%」がエスケープされて、「\%3」が「%253」になってる!

ではどうすればよいのか
RewriteRuleの[NE]フラグを使用するです。
[NE]フラグとは「No Escape」=「エスケープしない」。
「%」を「\%」とエスケープし、かつ[NE]でエスケープしない、とすればよいのです。

最終的には以下の形になります。
RewriteCond %{HTTP_USER_AGENT} IE的な何か
RewriteRule ^/(.*)$ http://example.com/redirect/http\%3A//example.co.jp/ [R=302,L,NE]


こうすると、「IE的な何か」のUAでリクエストを実行すると、
  1. http://example.com/redirect/http%3A//example.co.jp/みたいな形でリダイレクトされる
  2. http//example.co.jp/にリダイレクト
  3. 完了

JavaScriptが世界制覇しそうな予感

なぜかというと
米Yahoo!で議論された、フロントエンドエンジニアリングの将来(前編)という記事を発見しまして。
サーバサイドのJavaScriptという衝撃的な「node.js」に言及しています。
最近チラホラ聞きます(もっとも、本当に「サーバサイドのJavaScript」程度しか知らないのですが。。)

これはJavaScriptをもっと勉強しておいた方がよさそう。。

2010年11月15日月曜日

PHPで、1つのリクエストに対するcurlとcurl_multiとのパフォーマンスの差

複数リクエストの場合は
勿論、並列にリクエストを実行するcurl_multiの方が早いでしょう。
curl_multiを使っての実装方法はAPIとの通信効率をよくする実装例(1) curl_multi (Yahoo!JapanのTechBlog)に詳しく載っています。

じゃあ、リクエストが1つだけの場合は?
勿論、無駄な処理のないただのcURLの方が早いでしょう。
それは分かるけどどれくらいの差があるのでしょうか?
実験してみます。
PHPは5.2.5です。

ただのcURL場合
以下のプログラム(抜粋ですが)を10回試行して平均を取ってみます。
$url = "http://www.yahoo.co.jp/";

$start = microtime();

$res = my_curl($url);

if($res["info"]["http_code"] == 200){
  print("success");
}else{
  print("error");
}

$end = microtime();

function my_curl($url){
  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  $res = curl_exec($ch);

  $info = curl_getinfo($ch);
 
  return array("res" => $res, "info" => $info);
}


平均すると0.1679922秒かかりました。

curl_multiの場合
同じく、以下のプログラム(抜粋ですが)を10回試行して平均を取ってみます。
$url = "http://www.yahoo.co.jp/";

$start = microtime();

$res = my_curl_multi(array($url));

if($res[0]["info"]["http_code"] == 200){
  print("success");
}else{
  print("error");
}

$end = microtime();

function my_curl_multi($urls){

  $mh = curl_multi_init();
  $chs = array();
  foreach($urls as $url){
    $ch = curl_init($url);
    $chs[] = $ch;
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_multi_add_handle($mh, $ch);
  }

  do{
    curl_multi_exec($mh, $running);
  }while($running);

  $res = array();
  foreach($chs as $ch){
    $info = curl_getinfo($ch);
    $body = curl_multi_getcontent($ch);
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch);
  
    $res[] = array("res" => $body, "info" => $info);
  }

  curl_multi_close($mh);
 
  return $res;

}


平均すると0.300859秒かかりました。

まとめ
秒数自体は通信環境に因るところが大きいと思うので参考程度に…ですが、それにしてもコンマ数秒のオーダーで違ってきています。
並列処理をする必要がない場合は、極力通常のcURLを使用するのがよさそうです。

2010年11月12日金曜日

apacheの.confでUserAgentを判定する方法

こちらのブログに載っていたのでメモ。
%{HTTP_USER_AGENT}で判定できるらしい。

2010年11月3日水曜日

PHPで一時的なファイルを作成するときに、ファイル名の重複がないようにする

テンポラリファイルを作成して後で利用する処理などの場合、ファイル名が同じだとテンポラリファイルが上書きされてしまうかもしれない。
そのときの時分秒をファイル名に使用しても、重複する可能性はある。

ファイル名の重複を避ける便利な関数がある
tempnam関数を使えばよい。
この関数は、重複しないファイル名でサイズ0バイトのファイルを生成する。
返り値は生成したファイル名。
どういう原理で重複を避けてるのか。。

パフォーマンスへの影響は?
tempnam関数を使ってファイルを生成→削除した場合と、使用しないで生成→削除した場合の比較してみる。
PHP 5.2.5を使っています。

tempnam関数を使った場合
$time_start = microtime();
for($i = 0; $i < 1000; $i++){
 $filename = tempnam($dir, $prefix);
 unlink($filename);
}
$time_end = microtime();

上のようなサンプルを書いて試した(主要な部分のみ抜粋)。
tempnam関数を使ってファイル生成→削除を1000回ループまわしています。
10回試して平均した結果。
4.3750467(秒)

tempnam関数を使わない場合
$time_start = microtime();
for($i = 0; $i < 1000; $i++){
 $fp = fopen($dir.$prefix, "w");
 fclose($fp);
 unlink($dir.$prefix);
}
$time_end = microtime();

単純にファイル生成→削除を1000回ループまわしています。
10回試して平均した結果。
2.738844(秒)

1.5倍くらい違うという結果になった
tempnam関数を使用すると1.5倍くらい遅くなる、という結果になった。
そこまで劇的には変わらないようです。

でもどういう原理なんでしょうねー。

2010年10月31日日曜日

JavaScriptでよくある性能劣化ポイント

WEB+DB PRESS vol.59より。
自分のためのメモ代わりとして、気になった部分をピックアップ。

まずポイント列挙
JavaScriptコード上でよく見られる性能劣化ポイント(抜粋)。
以下、まず列挙します。リンクはページ内アンカです。
  1. 意図しない変数のグローバル化
  2. コストの高い配列アクセス方法を利用
  3. try/catchの間違った使用
  4. ブラウザの再描画について

意図しない変数のグローバル化
JavaScriptでは、関数内で変数を参照する際にまず自身のスコープ内を探します。
見つからない場合、入れ子になっている関数であれば外側の関数のスコープをたどっていき、グローバルスコープは必ず最後に探索されます(スコープチェイン)。そのため、グローバル変数を発見するのは時間がかかることになります。
また、「var」をつけずに宣言された変数はグローバル変数となります。
なので、グローバルにする必要のない変数は必ず「var」を付けて宣言しましょう。
関連:JavaScriptのクロージャ、スコープチェインについての記事(World Wide Windblue)

コストの高い配列アクセス方法を利用
配列にアクセスするには、以下の2通りの方法がある。
  1. メソッド呼び出し
    後発で使用追加されたメソッドを呼び出すこと。(Array.pushなど)
  2. プリミティブ操作
    原始的なアクセス方法

プリミティブ操作を使用するほうがパフォーマンスが高くなる。

try/catchの間違った使用
catch節が実行されるたびに新しいスコープが生成・破棄されるため、頻繁に実行されるとパフォーマンスが低下する可能性があります。
入力チェック時などエラー判定をするときなどでも、別の方法があるならtry/catch節を排除することが望ましいケースが多いでしょう。

2010 11/1 追記ここから
実際に試してみる。
エラー判定にtry/catchを使わない場合と使った場合で比較。
比較したブラウザはIE7、Firefox3.6.8、Google Chrome7、Opera10.63。
各検証を10回して平均を取った。

エラー判定にtry/catchを使わない場合。
window.onload = function(){
  var start = new Date();
  for(var i = 0;i < 10000; i++){
    var a = 100;
    if(typeof a === 'string'){
      return a.substring(0, 2);
    }else{
    }
  }
  var end = new Date();
  alert((end - start));
}

1回の実行にかかった平均の時間。
IE…11(ms)
Firefox…0.6
Google Chrome…0
Opera…1.9

エラー判定にtry/catchを使わない場合。
window.onload = function(){
  var start = new Date();
  var a = 100;
  for(var i = 0;i < 10000; i++){
    try{
      a.substring(0, 2);
    }catch(e){
    }
  }
  var end = new Date();
  alert((end - start));
}

1回の実行にかかった平均の時間。
IE…540.7(ms)
Firefox…760.7
Google Chrome…1395
Opera…28.9

(Operaが早すぎて不安です。PCのスペックが低いのも関係あるかもしれません)
2010 11/1 追記ここまで

また、catch節の実行時に生成されるスコープは、ローカルスコープよりも上位に位置します。
そのため、catch節の中で変数を定義することは、それだけで処理のオーバーヘッドになります。

ダメな例。
try{
  ...
}catch(error){
  if(error.code === '500'){
    var c = error.code;
    ...
  }
}

この倍、errorオブジェクトに対する処理は別の関数に委譲するコトでパフォーマンスへの影響を最小限に抑えられる。
関数かされた処理はcatchスコープから呼び出されても、ローカル変数は通常のローカル変数スコープ内に定義されます。
よい例。
try{
  ...
}catch(error){
  handleError(error);
}


ブラウザの再描画について
JavaScriptによりDOM要素の位置やサイズ変更、新たなDOM要素の追加などを行うと、ブラウザはその変更を表示されているWebページに反映しなくてはなりません。
このような場合にブラウザの再描画が発生しますが、再描画に要するコストは高く、頻繁に発生すると深刻なパフォーマンス低下を招きます。
再描画の回数を減らすポイントは次の2点。
  1. DOMに対する「スタイルの取得」と「スタイルの変更」を混ぜない
  2. DOMに対する「スタイルの変更」は短時間ですばやく行う

Webサイト高速化のルール

WEB+DB PRESS vol.59より。
14個列挙されていたものからいくつかピックアップ。

  1. Expiresヘッダを利用する
    サーバサオdpで付与可能なレスポンスヘッダで、該当するコンポーネントのキャッシュ有効範囲を設定できる。

  2. コンテンツはgzip圧縮する
    テキスト系コンポーネント(HTML/CSS/JavaScript)はgzip圧縮をすることでデータ量を大きく削減できる。
    ただし、ブラウザやバージョンの際によって問題が発生することもある。

  3. CSSは上に配置する
    CSSはheadタグ内にlinkタグで連続して配置しなければいけない。
    「@import」やHTMLの後半で指定するようなケースではレンダリングの遅延を招くケースがある。

  4. JavaScriptは下に配置する
    JavaScriptはほとんどのケースでbodyの閉じタグ直前に配置して問題のないケースが多い。
    HTML丈夫に記述するとダウンロードやレンダリングの中断を招く可能性があり、高速化の観点上、最も大きな遅延を招く可能性もある。

  5. DNS参照を最小限に抑える
    ページをダウンロードする際に、そのドメインの数だけDNSのルックアップ処理が発生するため。
    (CDNを利用するなどとは矛盾する部分もあるが…)

  6. Ajax通信はキャッシュする
    頻繁に発生しないリクエストやAjax通信によりサーバサイドでの更新処理が発生する場合など、キャッシュするべきかどうかを確認する必要がある。

Webサイト高速化に対する分析ツール

WEB+DB PRESS vol.59より。

  1. YSlow
    Yahoo!inc.が開発したWebサイトのパフォーマンス計測ツール→本家のサイト

    Firefoxで動作するアドオン。MozillaのAdd-onsページよりダウンロード可能。
    【ハウツー】YSlowでWebページを高速化 - リッチさと速さを同時に実現するUIを!(マイコミジャーナル)に使い方が載っている。

  2. Firebug
    こちらもFirefoxのAdd-onで動作する。ダウンロードページ→MozillaのAdd-onsページ
    HTMLやCSS、JavaScriptのデバッグやDOM操作を行うための開発ツール。

  3. AOL Pagetest
    Internet Explorer向けにALO Inc.が主体となって開発したオープンソースのツール。
    ダウンロードはこちらから。→SourceForge.net
    Firebugの「接続」タブのInternet Explorerのようなイメージらしい。
    AOL製のIE用Webパフォーマンスツール「Pagetest」(MOONGIFT)に詳しい使い方が紹介されている。

  4. Page Speed
    Googleが開発したFirefoxのadd-on。
    Googleのダウンロードページから入手できる。
    基本的にはYSlowに近い機能を持つよう。
    PageSpeed サイト応答速度調査ツール 使ってみました。 « SE99隊.jpに詳しい使い方が載っている。

2010年5月19日水曜日

Google Chrome Extensionsを開発してみる。

まだ途中です。

Google Chrome Extensionsとは

Googleの公式サイトはこちら

FirefoxのAdd-onのようなもので、ブラウザに拡張機能を提供できる。
Firefox Add-onよりも拡張できる機能は限定されているが、その分、開発が容易。

HTMLとJavaScriptとCSSのみで記述できる。

開発時に気をつける事

  1. ソースファイルの文字コードがUTF-8になっているか確認
  2. ソースのパスに日本語が含まれてはいけない。(「デスクトップ」など)。と思われる。

参考にしたリンク


  1. gihyo.jp - 続・先取り! Google Chrome Extensions

2010年4月25日日曜日

OAuthの概要について調べてみた

OAuthの概要
OAuthとは
  1. ユーザーのクレデンシャルを外部にさらすことなく、
    APIへのアクセス権を別のアプリケーションに譲渡するための、
    認証プロトコルの標準仕様。
  2. IDとパスワードの代わりにトークンを渡して、
    別のリソースへアクセスさせる

OAuthのフロー概要
まず、OAuthには登場人物が3人いる。
  1. ユーザ
  2. サービスプロバイダ
    (ユーザの認可情報を第三者に渡すサービス)
    Google、Yahoo!、twitterなど
  3. コンシューマ
    (サービスプロバイダから認可情報を受け取り,
    ユーザに代っていろいろな情報にアクセスしたり
    変更/追加を行ったりするサービス)


仮にユーザをUさん、サービスプロバイダをSさん、コンシューマをCさんとすると、
OAuthは以下のようなフローになる。

U「ねえねえ、Cくん。
君はオンラインショッピングのサービスを提供しているよね」
C「そうだよ」
U「いいサービスだと思うから、友達に紹介したいんだけど」
C「お、いいよ。誰に紹介したいの?」
U「Sくんのアドレスブックサービスに友達1000人くらい登録してるんだ。
その人たち全員に紹介したい。
Sくんのサービスで使っている僕のユーザ名とパスワードを教えるから
友達情報を取ってきてよ。
これから自由に使っていいし」
C「個人情報だだ漏れじゃないか!
 それに君がパスワード変えたときはどうするの?

ちょっと待ってて。Sくんと調整してみるよ」

C「Sくん。
僕のサービスと君のアドレスブックサービスを連携させて使いたい、
っていう人がいるんだけど」
S「個人情報入っているサービスじゃん。
アドレスブックサービスを使っていいか、
Cくんじゃなくて直接本人に確認したいな。
その人にこの割り符を持たせて、こちらに来るように言ってくれないか」
C「分かった」

C「という訳で、ちゃんとSくんに対して直接許可を与えて欲しい」
U「OK」

U「Sくん。
Cくんに僕のアドレスブックに入っている友達情報を教えて欲しい。」
S「その前にきみは誰だ?」
U「Uだよ」
S「なるほど。。
Uくん、君のアドレスブックの情報をCくんに教えていいんだな?」
U「うん」
S「割り符は? Cくんに渡しているはずだけど」
U「持ってきたよ」
S「おお、ぴったり合うな。分かった、じゃあCくんに教えるよ。
Cくんに、この許可証を渡してくれ。
Cくんがきみの個人情報にアクセスできるという許可証だ。
ちなみに1時間だけ有効だから。」
U「分かった。ありがとう」

U「Cくん。Sくんに許可を与えたから、
Sくんのアドレスブックサービスにアクセスしてよ。
許可証を渡されたから、これを持ってね!」
C「OK」

C「Sくん、君のサービスを使わせて欲しい」
S「ん?」
C「許可証も持っているよ」
S「なになに。。よし、いいよ。
使っていいよ」
C「ありがとう!
Uくんの友達の情報、ゲットだぜ!
早速この人たち全員に紹介しよう」

話が長くなりましたが、キモとしては、
Cくんは、
SくんのサービスでUくんが使っている
ユーザ名やパスワードを全く知らずに、
SくんのサービスからUくんの個人情報を知ることができた

ということです。

参考リンク
  1. @IT - APIアクセス権を委譲するプロトコル、OAuthを知る
  2. gihyo.jp - ゼロから学ぶOAuth 第1回 OAuthとは?―OAuthの概念とOAuthでできること

2010年4月18日日曜日

MacでAndroid開発 1.エミュレータを起動する

エミュレータ起動に必要だったもの概要
  1. Eclipse (バージョン3.5)
  2. Android SDK
  3. Android ADT

全部フリー!

では詳細な手順を書いていきます。

Eclipseをダウンロード
Eclipseのサイトより、
Eclipse IDE for Java Developers
をダウンロードします。

ここでいきなり問題なのが、Macの環境によって、
以下の2つのモノが用意されている点。

  1. Mac Carbon 32bit
  2. Mac Cocoa 32bitもしくは64bit


CarbonとCacaoの違い
ググったら以下のサイトを発見。
LCFE satellite
Mac初心者なので良く分からない事が多い。。けど自分的に大事だと思ったのは、

  • CocoaはObjective-Cもしくは、JAVAがメインの開発言語の開発環境
  • CarbonはC++/Cがメインの開発言語

の違い。
iPhoneアプリ開発もしたい(Objective-Cも使いたい)ので、
Cacaoの方を選択します。

で、
ダウンロードしたEclipseを適当なディレクトリに配置。

Android SDKをインストール
Download the Android SDK - Androidよりダウンロードして
適当な場所に展開して完了。

Android ADTをダウンロード
Eclipseのプラグインなので、まずEclipseを起動。
「Help」→「Install New Software」を選択。
すると「Available Software」という見出しのダイアログボックスが出てきます。
一番上の「Work with:」と書かれたテキストボックスに、
以下のURLを入力し、Addボタンを押します。
https://dl-ssl.google.com/android/eclipse/

すると、ダイアログ中央部に、何か利用可能な開発ツールの一覧が出てくるので、
チェックボックスにチェックし、次に進みます。
以降指示に従っていけばADTのダウンロードはできます。

インストール後の設定はここを参考にすれば
できます(手抜き)。

Hello World作成
ここを参考にすれば
できます(手抜き)。

いよいよエミュレータ起動
しようとしても何かエラーが出ました。

  • Your project contains error(s), please fix them before running your application.
  • No compatible targets were found. Do you wish to a add new Android Virtual Device?

エラーの対処法
以下のエラーが出る場合は、Vamp Recordsというブログが参考になると思います。
  • Your project contains error(s), please fix them before running your application.


また、以下のエラーが出る場合。
  • No compatible targets were found. Do you wish to a add new Android Virtual Device?

上記Vamp Recordsでも対処法が乗っていましたが、
対処できませんでした。
(ターミナルが「android」コマンドを認識してくれなかった)

ので、Eclipseから対処します。
Eclipseの「Window」→「Android SDK and AVD Manager」を選択。
ダイアログボックスが出てくるので、
左カラムの「Virtual Devices」を選択を選択した状態で、「New...」を押す。
で、「Name」と「Target」を好きなものにして「create AVD」を押す。
するとAVD(仮想でバイス)が作成されます。

これで上記エラーは出なくなりました。

エミュレータが起動できた
ただ一つ、コンソールに謎のワーニングが出ていました。
  • Warning once: This application, or a library it uses, is using NSQuickDrawView, which has been deprecated. Apps should cease use of QuickDraw and move to Quartz.

So Many People, So Many Different Ideasというブログによると、「これはAndroidのワーニングではないらしい。気にしなくてもよいとのこと」。「エミュレータのワーニングらしい」。

まとめ
フリーは素晴らしいです。

参考にさせて頂いたサイト
  1. Vamp Records
  2. @IT - Androidで動く携帯Javaアプリ作成入門(1)
  3. So Many People, So Many Different Ideas - 2009-10-07 はじめてのAndroidを読み始めました

Mac版Operaで前回終了時の状態を復元する方法

左上の「×」印で終了したらダメ
ではどうすればいいのかと言うと、
Operaメニューの「Operaを終了」で終了するんです。

タブを復元するのってかなり面倒くさいですよね。

Related Posts Plugin for WordPress, Blogger...