技術情報

EX-CLOUDの仮想化運用術

カテゴリ
ブックマーク数
このエントリーを含むはてなブックマーク はてなブックマーク - EX-CLOUDの仮想化運用術
このエントリーをはてなブックマークに追加
データホテル 田畑です。

データホテルで展開しているEX-CLOUDの仮想化には、Parallels Virtuozzo Containers(OpenVZの商用版)を使用しています。 Virtuozzoには特徴的な機能が色々ありますので、今日はその中から2点取り上げてみたいと思います。


■ストレージ不要のライブマイグレーション


他の仮想化技術では、二次記憶装置に外部ストレージを使用して、サーバに演算と一次記憶のみを任せることで、 ライブマイグレーションを実現させていますが、Virtuozzoではマイグレーション時にデータなどを移行先に同期させることで、 ストレージ不要のライブマイグレーション実現させています。 この機能は最初かなりビビッて使っていましたが、乗りこなしてしまえば実用に耐えますので、紹介したいと思います。

マイグレーションはおおまかに、以下のような流れで実行されます。
---------------------------------
1.移行先へデータ、プロセスの移行
2.メモリ内容の移行
3.IP付け替え
---------------------------------
マイグレーションはVirtuozzoカーネルが提供しているチェックポイント機能で実現されています。 マイグレーション時のプロセスを見ると、データ自体のやり取りはrsyncが使われています。

移行時は以下内容も保持されるので、無停止での移行と言って良いと思います。
---------------------------
起動プロセスとステータス
オープンファイル
ネットワークソケットと接続
---------------------------
IP付け替えの時にパケットが少し落ちますが、許容範囲内です。

注意点として、移行対象のVPSが作成されたテンプレートと全く同じテンプレートを移行先に用意しなければなりません。 これはOSテンプレートからキャッシュしたOSイメージを読み込んで、VPSを起動しているためです。

▽OSテンプレートとOSイメージについて


EX-CLOUDではEZテンプレートというテンプレートを使用しています。 EZテンプレートにはrpmなどのファイルは含まれておらず、リポジトリ、インストールパッケージ名などが書かれたテキストで構成されています。 このテキスト情報を元に、OSイメージ作成しています。

▽OSテンプレートcentos-5-x86_64の構成


Virtuozzoはディレクトリパスで、OSテンプレートを判別しています。
/vz/template/[OS名]/[バージョン]/[アーキテクチャ]/config/os/default/

centos-5-x86_64の場合以下のようなパスになります。
/vz/template/centos/5/x86_64/config/os/default/

このディレクトリ以下にテンプレート構成ファイルが配置されていて、 代表的なファイルは以下の2ファイルです。

packages:インストールするパッケージが記述されています。
------------------
authconfig
bash
crontabs
diffutils
rootfiles
info
・・・
・・・
・・・
------------------
repositories:レポジトリのリストが記述されています。
------------------
http://mirror.centos.org/centos/5/os/x86_64
http://mirror.centos.org/centos/5/updates/x86_64
------------------
以下を実行してテンプレートをキャッシュします。
# vzpkg create cache
すると、repositoriesからpackagesに記述されているパッケージが取得され、 OSイメージとしてtarボールに固められます。
/vz/template/cache/centos-5-x86_64.tar.gz
このOSイメージを元にVPSが作成されます。 実際に作成する場合はこんな感じです。
# vzctl create [VEID] --ostemplate centos-5-x86_64
ここでキャッシュしたOSイメージを消すとどうなるか? VPS内部では、OSイメージをリンクのような形で読み込んでいますので、 全構成ファイルがリンク切れファイルのような動きをします。 rm -rf / と同じ効果です。

■無停止でのリソース値変更


VirtuozzoはOS仮想化ですので、当然と言えばそれまでなのですが、 無停止でリソース値変更が可能です。 EX-CLOUDでは主に以下設定をプラン別に用意して、プラン変更があった場合は 無停止で割り当てリソースを上下させています。
---------------------------
CPU 使用量の制限値(cpulimit)
コンテナが消費するディスク容量の総サイズ(diskspace)
ディスク iノード数(diskinodes)
メモリの制限値(slmmemorylimit)
---------------------------
最近ではハイパーバイザ型もホットアド機能が実装されているので、 この優位性は無くなりつつありますが、気軽に設定変更出来る点では まだOS仮想化に分があるように思います。

▽CPU

Virtuozzoのcpulimitは%単位で設定を行います。 CPUコア数×100%が全体の処理能力になりますので、QuadCore+HTのサーバだと 8*100=800%が全体の処理能力です。

CPU使用量の制限値されたVPS内部では/proc/cpuinfoのcpu MHzが変化します。
制限なし
cpu MHz         : 1862.037

25%制限
cpu MHz         : 352.768
VirtuozzoがMHz単位でCPUリソースを割り振ってるわけでは無いのですが、 表現としてはわかりやすくて良いと思います。

▽ディスク

ディスクを100GB使っているVPSのディスク容量を50GBに縮小するとどうなるか?
Size:50GB、Used:50GB、Avail:0GB
もちろんディスクフルになりますが、100GBのデータにはフルアクセス出来ます。 50GB以下にディスクを減らすと50GBでキャップされます。 良く出来てます。

▽メモリ

メモリを2GB使っているのVPSのメモリ容量を1GBに縮小するとどうなるのか?
OOM Killerにプロセスがバッサリkillされます。 こっちは容赦無いです。


このような機能を使いながらEX-CLOUDの運用をしているのですが、 そのEX-CLOUDから低価格VPSプランEX-LITE(エクスライト)を先日リリースしました。

http://ex-cloud.jp/ex-lite/

EX-LITE(エクスライト)の特徴

・1U(SASディスク 30GB、メモリ1GB)あたり月額1,050円
・1U〜5Uまで無停止スケールアップ可能
・WebDAV設定済みですぐ使える
・LANも使える(別料金)

低価格VPSのこのプラン、初期無料&最低利用期間が1ヶ月となっています。 サーバーエンジニアの方々による検証環境や開発環境としての活用事例が増えてきていますので、 皆さんも機会があれば是非ご検討いただければと思います。

鉄道情報APIをロケタッチでリリースしましたのお知らせ

カテゴリ
ブックマーク数
このエントリーを含むはてなブックマーク はてなブックマーク - 鉄道情報APIをロケタッチでリリースしましたのお知らせ
このエントリーをはてなブックマークに追加
にどめまして!前回の住所正規化 APIが好評なようで花粉症が吹き飛んでいた Yappo です。
さて、今回は表題の通り鉄道情報 APIをリリースしたのお知らせです。

鉄道情報 API ってなに?

日本国内の鉄道路線や鉄道駅を検索する事が出来る API です。
例えば、路線一覧山手線の駅一覧を JSON 形式で簡単に取得出来ます。

基本的にはデータソースとして駅データ様のデータを利用しているため、基本的には駅データの仕様に準拠していますが、ロケタッチ独自の情報を付与したデータを返しています。

使い方

使い方は簡単で、前回の住所正規化 API のように単純に GET リクエストを飛ばすだけで良いです。

例えば山手線の全駅リストを Perl で書きたい場合には以下のように書きます。
use strict;
use warnings;
use 5.016;
use JSON;
use LWP::Simple;
use URI;
binmode STDOUT => 'utf8';

my $uri = URI->new('https://api.loctouch.com/v1/railway/stations?line_cd=11302');
my $json = get($uri);
my $data = decode_json($json);
for my $station (@{ $data->{stations} }) {
    say "$station->{spot_line_name} $station->{spot_station_name}";
}
レスポンスデータとしては、基本的には駅データの仕様通りのものが入っていますが、以下のロケタッチ独自のデータも付与されています。
spot_line_name ロケタッチ独自ルールの路線名
spot_station_name ロケタッチ独自ルールの駅名
spot_id この駅に対応するロケタッチの駅カテゴリのスポットID
station_spot_id この駅に対応するロケタッチの路線別駅カテゴリのスポットID
geohash lon lat を geohash 化した文字列
元のデータソースの場合は、駅名の suffix (駅、電停)などが入っていなかったり、路線名が一般的ではない(例えばりんかい線が東京臨海高速鉄道になっている)ものがあったり、駅名の表記が厳密に正しくないものがあったり、ロケタッチの駅スポット名のポリシーと相違があるルールになっていた為、 spot_line_name と spot_station_name という key に独自ルールの名称を入れています。

この他には元のデータソースには無い新幹線のデータが下記のように入っています。 これ以外にも複数 API を用意してありますので、その他の詳細はドキュメントをご覧下さい。

API 実装の背景

鉄道駅というものは、日本の社会において重要拠点といって良いスポットです。ロケタッチで保有/メンテナンスしている大量のスポットを、どう社会に還元しようかを考えた結果、駅を拠点として周辺案内をする駅前案内というサービスをβリリースしました。
また、それらと平行して何かとご意見を頂いていたロケタッチの駅スポットの整備を進めていて、駅情報のノウハウが高まりました。

こうした駅関連の整備が一段落したので、データソースである駅データ様の駅データ仕様共通化のため無料でデータを公開しているという理念に共感したため、区切りが良いので API 公開に踏み切りました。
と、カッコいい事を書いてみたんですが実際は社内の別プロジェクトで「駅情報あつかういい方法無い?」って言ってる人が居たので作っただけですすいません。

まとめ

最後にまとめると

  • 鉄道情報 API をリリースしました
  • 実装の背景を説明しました
  • レスポンスに含まれるロケタッチ独自データの説明をしました
  • 駅データを利用しているサービスさんは、ロケタッチとマッシュアップしやすくなりました
  • 今回の件もたぶんYAPC::Asia Tokyo 2012 で Open&Share すると思います
といった内容のエントリを書かせて頂きました。

もし利用したときに気になった事、ご意見等がございましたらロケタッチ Developers Forumまで feedback をお寄せいただければ幸いです。


どうぞご利用下さい。

住所正規化APIをロケタッチでリリースしたよ!1

カテゴリ
ブックマーク数
このエントリーを含むはてなブックマーク はてなブックマーク - 住所正規化APIをロケタッチでリリースしたよ!1
このエントリーをはてなブックマークに追加
LINE が PC から使えるようになって、自社サービスなのに wktk しながらハックしてた大沢Yappo和宏です。こんにちわ。初めましての人は初めましてね。

今回は、先日ロケタッチの API に、住所正規化 APIを追加したので簡単な紹介をします。

ロケタッチ API って何?

ロケタッチ API は、ロケタッチのユーザーデータ、スポットデータ、チェックインデータ等にアクセスできる API です。
OAuth2 で実装されているので、どのような言語からも利用しやすくブラウザだけで完結するような JavaScript アプリケーション等にも気軽に導入する事が出来ます。

Perl の世界だと Amon2 という Web Application Framework の認証プラグインとしてAmon2::Auth::Site::Loctouchが CPAN にあるので、これを使うと簡単にロケタッチアプリケーションを書く事が出来ます。

住所正規化 API ってなに?

住所というのは人によって書き方が変わってくるものですが、この個人差がある住所を一定のルールに沿って正規化をする為に使える API です。

例えば東京都品川区大崎2-1-1 ThinkPark Tower 23階と言う住所は以下のようにも表現出来ます。

  • 東京都品川区大崎2丁目1番1号 ThinkPark Tower 23階(丁目以降の表記を漢字と数字で表す)
  • 東京都品川区大崎2の1の1 ThinkPark Tower 23階(- の変わりに の)
  • 東京都品川区大崎2−1−1 ThinkPark Tower 23階(数字部分が全角)
  • 東京都品川区大崎2-1-1ThinkPark Tower 23階(ビル名の区切りがわからない)
  • 品川区大崎2-1-1 ThinkPark Tower 23階(都道府県を省略)
  • 東京都大崎2-1-1 ThinkPark Tower 23階(自治体名を省略)
こういった自由な感じの住所を、足りない部分を補完しつつ数字部分の書式を統一して東京都品川区大崎2-1-1 ThinkPark Tower 23階と変換します。

使い方

単純な JSON API なので、単純に GET リクエストを飛ばすだけで良いです。
https://api.loctouch.com/v1/geo/address_normalize?address=[正規化処理したい住所]
という URL にアクセスすると正規化された住所を含んだ JSON が帰ってきます。

例えば札幌市役所の住所を変換する処理を Perl で書きたい場合には以下のように書きます。
use strict;
use warnings;
use 5.015;
use JSON;
use LWP::Simple;
use URI;

my $uri = URI->new('https://api.loctouch.com/v1/geo/address_normalize');
$uri->query_form(address => '札幌市中央区北1-西2');
my $json = get($uri);
my $data = decode_json($json);
say $data->{result}{address}; # 北海道札幌市中央区北一条西2丁目
戻ってくるデータとしては、正規化後の住所の自治体コード、郵便番号、○○県○○市などの自治体名、町域、丁目番地号などの数字部分、ビル名がそれぞれ別の項目として JSON に含めています。

ロケタッチ Developers サイトでは、 JSON API をブラウザで確認出来るAPI Explorer(要ロケタッチのログイン)があり、これを使って簡単に確認する事も出来ます。

49

その他の詳細はドキュメントをご覧下さい。

どうして作ったの?

ロケタッチでは様々なスポットデータが登録されています。そのスポットの属性として住所情報も登録されているのですが、基本的には利用者の皆様の手作業によって住所情報が埋められています。
人によって住所の書き方が違うと言うのは先ほど述べた通りですが、ロケタッチではスポットに登録されている住所を元にして(NDA)な事をやろうと計画しているため、住所表記の正規化は重要なミッションでした。

わかりやすい例だと、同じ住所のスポットがいくつかあった場合には重複したスポット同士の可能性があるので、それぞれのスポットをマーキングしておくことによってデータメンテナンスの効率が捗ります。
他にも、同一住所で同じビル名のスポットを集めておいて、おっと誰かが来たようだ。

本当はサービスの中だけで使う API として実装していたのですが、他の位置情報関係の API を見渡しても住所正規化に特化した API は見当たらなかったので「これは Open & Share したら有用なんじゃないか?」と言った意見が社内で出てきたのでロケタッチ API として出す事になりました。

どうやって作ったの?

「膨大な住所データベースを元に正規化しているんじゃないか?」と思う方も居るでしょうが、実際には住所データを元にした巨大な正規表現を使って処理しています。

都道府県が抜けた住所の補完や、東京都南青山などのように真ん中の部分が抜けた住所の穴を埋める為に、正規表現を駆使して妥当な候補を選んで、確実な候補だけを返すようにしています。

でかい正規表現としてもモジュールファイルのサイズとしては二桁メガバイトなのですが、 plackup してモジュールをロードした後のメモリ使用量は200MBを越えます。 use するだけでも数秒かかってしまう壮大なものになってますが、一度ロードされたら変換速度は速いのでロケタッチ API で使う分には十分だろうという事で公開に踏み切りました。

でかい正規表現の他にも、各地域の住所表記に合わせた泥臭い処理は多数入っていますけどね。。。

今は郵便番号を返す部分だけ手抜きして MySQL にクエリ投げちゃってるのですが、これもモジュールファイル化する予定なので、実質的には IO 処理が一切走らない実装になる予定です。

まとめ

最後にまとめると

  • 住所正規化 API をリリースしました
  • 住所正規化の重要性を簡単に説明しました
  • どのような仕組みで実装されているかの簡素な説明を行いました
  • 実装に関する基本的な考え方や基礎については、私の6年前の Shibuya.PM の資料5年前の YAPC::Asia の資料をご覧下さい
  • もっと詳しい内容に関しては、どこかのカンファレンスで Open & Sahre するかもしれません
といった内容のエントリを書かせて頂きました。

現在は、ロケタッチに登録されている住所に最適化されてる部分があるので、もし利用したときに気になった事、ご意見等がございましたらロケタッチ Developers Forumまで feedback をお寄せいただければ幸いです。


どうぞご利用下さい。

本当はもっと速いImlib2: Imlib2でもImageMagickと同じ仕組みでサムネイル画像生成を速くする方法

カテゴリ
ブックマーク数
このエントリーを含むはてなブックマーク はてなブックマーク - 本当はもっと速いImlib2: Imlib2でもImageMagickと同じ仕組みでサムネイル画像生成を速くする方法
このエントリーをはてなブックマークに追加
こんにちは!こんにちは!
開発部のやましーです。
今回はSmallLightの中でやっている細かいことについてです。



SmallLightとは


SmallLightとは、2010年末にlivedoor labs EDGEにてリリースした画像サムネイル生成用Apacheモジュールです。



JPEG画像の読み込み処理の最適化

JPEG画像は、その圧縮アルゴリズムの特性で読み込み時に1/2、1/4、1/8にダウンスケーリングすることができます。libjpegでは画像読み込み時にjpeg_decompress_struct構造体のscale_denomにダウンスケーリング指数を指定します。

SmallLightではこれをJPEGヒントオプションとして実装しています。パターン文字列に jpeghint=y を付与することで有効になります。(SmallLightの README の100行目)

JPEGヒントオプションはImageMagickとImlib2に実装してあります。
それぞれの実装は下記のようになっています。

ImageMagick

ImageMagickには既にこの処理が備わっています。
詳しくは下記のページにて解説つきで詳しく述べられています。

本当は速いImageMagick: サムネイル画像生成を10倍速くする方法

具体的にはというと、ImageMagickは「jpeg:size」オプションを渡すことで自動的にscale_denomによるダウンスケーリングをさせることが出来るため、118行目辺りにMagickSetOptionでjpeg:sizeをセットするコードを追加しただけです。

Imlib2

Imlib2にはこの処理をできるオプションが無かったため、JPEGローダーの部分をSmallLight側に内包しました。

load_jpeg関数のコードの場所は73行目辺りになります。先にJPEGヘッダー情報から画像サイズを取得し、この関数が呼ばれるときに渡された縮小後のサイズを元にscale_denom値を指定しています。load_jpeg関数はピクセルデータを返すので、Imlib2のimlib_create_image_using_dataを使用してピクセルデータからImageインスタンスを生成しています。



ベンチマークテスト

上記のJPEGヒントオプションでの最適化を行わない場合と行った場合の処理速度のベンチマークテストを行いました。

条件


ベンチマークテストの実施条件。

  • 画像変換エンジンはImageMagickとImlib2を使用
  • 大きい画像2560x1920と小さい画像640x480を、それぞれ250x187に縮小する処理を100回繰り返す
  • JPEGヒントオプション利用の有無
  • 画像キャッシュなどは行わない

結果

ベンチマークテストの実施結果。

エンジン 画像サイズ JPEGヒント
無効 有効
ImageMagick 2560x1920 43.39s 12.96s
640x480 8.53s 8.41s
Imlib2 2560x1920 10.55s 3.06s
640x480 0.69s 0.70s
この結果からは、ImageMagickもImlib2もJPEGヒントを有効にすると画像サイズ2560x1920の処理時間は1/3〜1/4程度の短縮が見られ、画像サイズ640x480はほとんど変わらないことが分かります。これは画像の読み込み時に予めダウンスケーリングするという最適化の処理なので、画像サイズ2560x1920は640x480に大きくダウンスケーリングされるため読み込み速度の短縮に大きく影響しますが、画像サイズ640x480はこれ以上小さく読み込めずダウンスケーリングされないためです。

読み込み・変換・保存の処理時間

具体的にどの処理時間がどれくらい短縮したのかを見るために、画像サイズ2560x1920の読み込み・変換・保存の処理時間を計測しました。

エンジン 処理 JPEGヒント
無効 有効
ImageMagick 読み込み 221ms 48ms
変換 233ms 88ms
保存 4ms 4ms
Imlib2 読み込み 186ms 44ms
変換 15ms 1ms
保存 2ms 2ms
ImageMagickもImlib2も読み込み処理時間の短縮と共に変換処理時間も短縮されています。これは通常は2560x1920の画像を250x187へ縮小していたのが、最適化による読み込み時のダウンスケーリングによって640x480の画像を250x187へ縮小すればよくなったためです。



課題


読み込み処理の最適化

現在のSmallLightは、基本的に全てをImageMagickやImlib2に任せてあまり複雑化させないように作り始めたので、読み込み処理の最適化は行われていません。ImageMagickやImlib2はメモリ上に用意した元画像のバイナリ、またはファイルから画像を読み込むため、その辺の最適化はやりにくいところです。
しかし直接libjpegなどの画像ライブラリを使えば、フィルターの入力ストリームを徐々にライブラリに渡すことで元画像サイズ分の入力バッファを持たなくて済むため、無駄なメモリ間のコピーやメモリ消費量を抑えることができます。

Imlib2でのGIF形式の出力

Imlib2のGIFローダープラグインはGIF形式の出力に対応していません。現状では元画像がGIF形式ならJPEG形式で出力するなどの回避策が必要なので、GIF形式での出力機能を内包するなどの対応をする必要があります。


今後もSmallLightのような「地味だけど結構需要があったりする小物」を何か作って公開していければと思います。

Eclipse苦手者がAndroid開発する際に押さえるべきこと

カテゴリ
ブックマーク数
このエントリーを含むはてなブックマーク はてなブックマーク - Eclipse苦手者がAndroid開発する際に押さえるべきこと
このエントリーをはてなブックマークに追加

こんにちは! スマートフォンアプリ開発チームのfaultierです! 得意な口説き文句は「君のprotocolにconformしたい」ですが、今のところ使ったことはありません。

みなさん、普段の開発ではエディタは何を使ってますか? きっとvimかemacsかメモ帳か念力による直接入力を使っていると思います。ちなみに僕はvim派です。出社したらまずはブラウザ・ターミナル・IRCクラインアント・Twitterクライアント・iTunesを立ち上げ、可能な限りその中から出ないことを心がけています。

前回は同じチームのgaoohさんがEclipseによるAndroid開発環境の作り方を解説していましたが、今回はそれに便乗して、出来るかぎりターミナルから出たくない不精者のためのEclipseを使わないAndroid開発環境を作るときに押さえておくべきことを、リーダーに言われてもいないのにまとめてみました。

AndroidSDKのツール群を使う

AndroidSDKをインストールすると、Androidを作るのに必要なフレームワークやAndroidエミュレータだけでなく、コマンドラインから使うツール郡も一緒にインストールされます。なにはともあれ、$SDK_HOME/toolsや$SDK_HOME/platform-toolsにパスを通して、これらのツールを使えるようにしておきましょう。

android

そのものずばり、androidコマンドです。AVD(Android Virtual Device、エミュレータで動かすAndroidの仮想デバイス)やSDKの管理、Androidプロジェクトの雛形を作ったりできます。特に覚えておく必要があるサブコマンドを以下に挙げますが、他にできることやそれぞれのサブコマンドのオプション等は-hオプションを付けて確認してください。

list|create|move|delete|update avd
AVDの管理をするサブコマンドです。EclipseやAVDマネージャからGUIで作ることもできますが、androidコマンドを使えばCUIで管理することもできます。
create (test-)project
Androidプロジェクトの雛形を作ります。バージョンや環境によって変わると思いますが、僕の手元のSDKでは、AndroidManifest.xml、メインのActivityとレイアウト、アイコン、string.xml、ant用のbuild.xml、ProGuard用のproguard.cfgなどを用意してくれました。
update sdk
Eclipse+ADT環境であればEclipseから各バージョン向けのライブラリやエミュレータを取得/更新できますが、Eclipseを使わない場合はandroidコマンドから行ないます。実行するとSDK and AVDマネージャが立ち上がり、SDKの更新があればダウンロードできます。また、サードパーティのAdd-onもいくつか(この記事を書いた時点ではGoogle API Add-onとSamsung GALAXY TAB Add-onが利用可能です)ここからインストールできます。

emulator

エミュレータを起動するコマンドです。android list avdでAVDを確認して、emulator @AVD_NAMEでエミュレータ起動です。こちらも細かい起動オプションを付けることができ、回線速度や遅延、プロキシやリダイレクトの設定などもできます(エミュレータでデバッグしているとついつい3G回線の遅さを見過してしまうので、起動オプションで3G回線の設定にしておきましょう)。なお、エミュレータはtelnet接続して起動後に設定を変更することもできます。

adb

エミュレータやデバイスを制御するコマンドです。アプリケーションのインストール/アンインストール、ログの表示、仮想デバイスに接続してのshell起動など、CUIでAndroid開発をするときにはこれを使わないことには始まりません。

-eオプション、-dオプション、-sオプション
-eオプションを付ければ起動中のエミュレータを、-dオプションを付ければUSBデバッグモードの実機を制御するようになります。それぞれ複数接続している場合は、adb devicesでデバイスのシリアルナンバーを確認して、-sオプションで指定することでそのデバイスを制御することができます。
install/uninstall
アプリケーションのインストール/アンインストールをするサブコマンドです。インストールするときはapkファイルのパスを、アンインストールをするときはパッケージ名を指定します。
pull/push
直接デバイスに、もしくはデバイスからファイルをコピーするサブコマンドです。
logcat
端末のログを表示します。android.util.Logを使って出力したログはこれで見ることができます。
shell
端末に接続してadbシェルを起動します。SDカード内のファイルを直に操作したり、amコマンドでインテントを送ったり、sqlite3コマンドでDBの中身をいじったりできます。
forward
ローカルのソケットをデバイスに転送できます。TCPやUnixドメインソケットだけでなく、JDWPにもフォワードできます。

ddms

前回の記事でも出てきたDDMS、これはEclipseやADTの機能ではなくAndroidSDKに付属しているツールですので、ddmsコマンドで単体で起動できます。

keytoolとjarsignerを使う

Eclipse+ADTで開発している場合は、鍵を作ったり署名したりもEclipse上でできますが、Eclipseを使わない場合はkeytoolとjarsignerというtoolを使って自分でやる必要があります。keytool -keygenで鍵を作って、jarsignerでapkファイルに署名です。鍵の作り方や署名方法はドキュメントを参考にしてください。

jdbを使う

デバッガが無いとデバッグプリントでも仕込んでlogcatで見るくらいしか手段が無くて大変面倒ですが、ちゃんとjdbを繋いでデバッグすることができます。adb shellからamコマンドで-e debug trueオプションを付けてインテントを送ってアプリを起動し、adb jdwpで一覧表示してJDWPのPIDを探し、adb forward tcp:PORT jdwp:PIDで転送の設定をして、jdb -attach localhost:PORTで接続できるようになります。

mavenを使う

普通にJavaファイルをコンパイルして、dxコマンドでclassファイルをバイナリに変換、apkbuilderでapk作成、という手順で作ることもできますが、面倒なだけなのでそこは自動化してしまいましょう。androidコマンドでcreateすればant用のbuild.xmlなども生成されますが、mavenの方が便利そうだったので僕はmaven-android-pluginを使っています。

一つ一つ説明していくとそれだけで一記事書けそうなボリュームだったので、サンプルプロジェクトを用意してみました。Hello worldアプリケーションのプロジェクトとそのテストプロジェクトをandroidコマンドで作り、二つのプロジェクトをmavenのマルチプロジェクトの形で一つのプロジェクトにしてあります。チェックアウトしたら、(mavenをインストールして)親ディレクトリでmvnコマンドを実行すると、依存ライブラリのインストール、エミュレータの起動、アプリケーションのビルド、apkファイルの生成、インストール、テストの実行までコマンド一発でやってくれます。

テスト用のプロファイルとディストリビューション用のプロファイルを用意してあるので、(署名用のキーの生成などを事前に行なって)mvn clean package -Pdistributionを実行すると、今度はテストは行なわず、ProGuardによる最適化・難読化、署名などを行なったapkファイルがsample-app/targetの下に生成されます。

vimを使う

最初に僕はvim派だと宣言したので、ここではvimでコードを書くときに便利なものをいくつか紹介します。emacsでも同じように便利なものがあると思うので、emacs派の方はここは読み飛ばしてもらって自分で便利ツールを探して下さい。

taglist

ソースコード中のクラスやメソッドをアウトライン表示してくれるプラグインです。Eclipseのアウトラインビューみたいになります。

FuzzyFinder

ファイル名やクラス名、メソッド名などから簡単にファイルを探して開けるようにしてくれるプラグインです。探す対象も、開いているバッファ、タグ、最近開いたファイルなどから選ぶことができ、部分一致や曖昧な補完などもしてくれるので、恐しく便利です。特にJavaだとsrc以下の階層が深くなりがちですが、いちいちパス打ってられっか、とイライラしたりする必要はありません。

neocomplcache+snipMate

普段PerlやRubyを書いてるWebエンジニアから見ると、Javaは所謂「おまじない」多い言語に見えますが、あんなものをいちいちタイプしてたら日が暮れます。Eclipseを使っている同僚のディスプレイをこっそり後ろからのぞいて見ると、コード補完やスニペットを活用して自分で書かずにEclipseに書かせていました。当然ですがvimで書くときも、自分で書かずにvimにやらせてしまうのが正しい怠け者の生き方です。

neocomplcacheはコード補完を便利にするプラグインで、snipMateはスニペットを簡単に使えるようにしてくれるプラグインです。neocomplcacheを入れておけば、何か打てば補完候補が出てくるので、あとはその中から適切なものを選ぶだけの簡単なお仕事になります。それだけだとクラス名やメソッド名を補完してくれるだけなので、よく書くコードはスニペットにしてしまいましょう。neocomplcache自体にもスニペット機能が付いていますが、snipMateの方が個人的には書き易く、を連携させることもできるので、そっちを使っています。

最後に

色々紹介してきて最後に全部ひっくりかえすようでなんですが、Javaを書くなら正直なところEclipse(や他のIDE)の方がずっと便利です。Javaに関してなら、コード補完や整形、リファクタリングやテスト、デバッガとの連携など、賢くやってくれますし。なので例えば、

  • Androidアプリに集中したいのに、iPhoneアプリのためにObjective-CやCを書いたり、サーバサイドのアプリのためにPerlやRubyを書いたり、WebインターフェースのためにHTMLやJavaScriptを書いたりすることが稀によく頻繁に毎日ある
  • 上司や嫁/旦那に泣きついてみたものの、設備投資の予算が獲得できなかった
  • 「この人と、添い遂げたい」と心に決めたエディタがいる
  • 文字しか表示されてない画面を見ていると心が落ち着く
  • テンキーは隣村にあり、マウスは地の果てにあると思っている

みたいな項目に心当たりがあるような人だったら、非Eclipse環境に手を出してみてもいいんじゃないかなと思います。逆に、

  • 当面Androidアプリしか作らない
  • あるいは、普段からJavaのお仕事をしている
  • 画面に文字しか表示されてないと精神が不安定になる
  • 「えーマジメモリ不足!?」「キモーイ」「Eclipse起動した程度で重くなるPCが許されるのは小学生までだよねー」「キャハハハハハハ」と思っている

みたいな項目にいくつかあてはまるような人は、普通にEclipseを使ってもいいんじゃないかな、と思います。とは言え、好みの環境を組み合わせられたり、自動化したりすることもできるので、普段はEclipseを使う人も知っていても損は無いんじゃないでしょうか。ということで、EclipseとADTだけがAndroid開発環境じゃないんだよという紹介でした!