これはGoogleによって開発された携帯端末向けプラットフォームであり、開発環境も現在無償で提供されている。
AndroidのOSは、Linuxをカーネルにした、JavaVM(Dalvik)を独自実装し、Nativeで動作するモジュールなどをJavaと連携できるような仕組みとなっている。
Javaは非常に洗練された言語構造を持ち、またハードに依存しないように、VM(Virtual Machine)という仮想マシンを想定した中間コードをインタプリタ言語のように実行するため動作が遅い。しかしAndroidのJavaVMである、DalvikではJIT(JustInTime、Android 2.2以降)により、実行時に中間コードをNativeコードとして保管し実行させることで高速化がはかられ、また通常のJavaVMでは、ハードウェアに依存しないように、スタックベース(計算などに利用する値などを一旦スタックに置いてから計算が実行される。これによってハードが何個レジスターを持っていようが、レジスターの種類などハードに依存せずに計算実行できる)で動作するが、Dakvikは高速化させるために、レジスターベースの動作が行われ、通常のJavaVMよりも高速化されている。そのためにDalvikでは中間コードに、DEX(Dalvik Executable)という形式で、レジスター方式の弊害である中間コードの増大に対して自動的に最適化を行い、極力中間コードを減らすように設計されている。(Dalvikは開発者の名前から命名)
Intentは直訳すると意図や意思という意味であるが、Androidでは基本的にデータをやり取りするフォーマットのような認識が近いだろう。基本的にはActivityに対してIntentデータを送る事で他のActivityが起動される。ただIntentには2種類の仕組みがある。1つは明示的で、Intentは送り先のアクティビティを指定して送信する基本的なパターンと、Activityを指定せず、Intentは設定されたActionを元に、システムに登録されているアクティビティの中から同じActionを持つActivityを起動する暗黙的なIntentがある。この暗黙的Intentは分かりづらいが、例を見ると分かりやすい。
//壁紙を変更するIntentを作成し Intent int = new Intent(Intent.ACTION_SET_WALLPAPER); startActivity(int);
これは、ACTION_SET_WALLPAPERというActionを持つActivityを起動するコードであり、ポイントは明示的Intentと違い、起動するActivity名を指定していない。このようなコードが起動されると、この壁紙を変更するという機能を持ったActivityの一覧が画面に自動的に表示され、どのActivityを起動するかユーザーに通知する。(1つしかActivityが無い場合は自動起動)
さらにAndroid2.2では、これらのIntent通知をネットワークを介したCloud to Device Messaging(C2DM)が提供されており、例えばPCのブラウザで見たページを、Android端末のActivityに通知をすることで連携が取れるようになっている。詳しくはこのページを参照の事
ID名 | 概要 |
電話番号 | 内蔵される SIMカードに記録されている、電話を利用するための番号 |
International Mobile Equipment Identity(IMEI) | ほぼすべての携帯電話に付与される15桁の端末固有ID。 |
Android ID | Android OSが初回起動時に生成する16桁の乱数。端末によってはnull(ヌル)値を返すこともあり、端末識別子としては不完全という指摘もある。 |
IDEはEclipseを利用し、Android Pluginを導入することで、開発環境が一式そろう。
Androidの公式サイト
Androidの開発環境は大きくわけて3つ。
http://dl-ssl.google.com/android/eclipse/
以前のADTでは、PreferencesのAndroidの項目に、NDKという項目があったが、最新のADTからは、どうやら方式が変わったようだ。
Preferences -> C/C++ -> Build -> Environment のページに、
通常、Androidのプロジェクトを作成するには、Eclipseのメニューから「ファイル」を選択し「新規」−>「Android Project」を選択する。但しその際には以下の項目を必須とする。
Project Name | 自分ですきなプロジェクト名を設定する。英語が推奨 |
Build target | Android SDK のバージョンを指定する |
Application Name | 必要ないが通常はここでアプリ名を設定しておく |
Package Name | com.domain.android.helloworld などのような命名規則でパッケージ名を指定 |
Create Activity | チェックはONにして、Activity Nameを設定する |
androidでは、特殊なフォルダ構成が存在する。詳しくはここのサイトに詳しく記載されている。
上記のページに書かれているリソースフォルダに入れたリソースファイルには、自動的にプロジェクトフォルダ配下のgenフォルダに、R.javaというファイルが自動生成(F5キーを押して、最新の状態にプロジェクトを更新するタイミングで生成)され、androidのソースからアクセスするためのresidという形式になって、アクセスできるようになる。
ビルドパスエントリーをプロジェクトにする
eclipseの環境設定から、Java -> ビルドパスを選択すると、デフォルトのビルドパスエントリーの設定をする画面がある、ここでプロジェクトを選択しておく。
INSTALL_FAILED_INSUFFICIENT_STORAGE
通常、上記のようなエラーの場合にはtemp容量が足りない場合が多い。そのため、一度adbからアプリをアンインストールしてから実行してみると良い。
adb uninstall com.example.android.apis
logcat を見たい時
adb logcat
オプションの詳細を確認したい場合にはここを参照。
Failed to installが表示され、インストールが出来ない
Androidでは携帯電話特有の少ないリソース(メモリ、CPU速度など)でアプリを稼働されるため、プログラムが動作する上で下記のような動作が行われる。
このビューの事をAndroidでは、Activityという言い方をする
androidでは、このActivityを継承することがメイン処理ということになる。
import android.app.Activity; public class MyApps extends Activity { メイン }
また先の説明の通りこのアクティビティには下記の規定されたメソッドが必要となる。
生存期間種別 | メソッド名 | 機能概要 |
entire lifetime (必須メソッド) | onCreate | アプリがロード時に処理される。コンストラクタ |
onDestroy | Activityが終了した時 | |
visible lifetime | onStart | アプリが動き出した時に呼び出される |
onStop | 長期に見えない所にあるActivityの場合呼び出される。メモリ解放も行う。 | |
onRestart | onStopの状態が復帰した場合に呼び出される。onRestartの後はonStartも呼ばれる | |
foreground lifetime | onPause | ActivityからForegroundが外れた時 |
onResume | ActivityにForegroundが戻った時 |
上記の特徴を鑑みるに以下基本設計を心がける
Androidでは、このActivityという概念が重要であることは、上記の説明で伝わっていると思われるが、これに付随する仕様でIntent(直訳:行うべき事・意志)というものがある。これは端的に説明すると、Activityが持つ呼び出しのインターフェイスと、戻り値の引き渡しインターフェイスを纏めた概念である。
注意点として、アプリ名指定するのではなく、機能を指定するということが大きな特徴であり、該当するIntentを持つアプリが複数あった場合は、ユーザーがその中から選ぶ仕組みになっている
呼び出し側のActivityで記述する内容例
// 他のActivityの呼び出し public void onClick(View v) { Intent intent = new Intent("com.google.zxing.client.android.SCAN"); startActivityForResult(intent, REQUEST_CODE); } // Activityの呼び出し結果の処理 protected void onActivityResult(int reqCode, int resCode, Intent data) { if( reqCode == REQUEST_CODE && resCode == Activity.RESULT_OK){ String contents = data.getStringExtra("SCAN_RESULT"); TextView t = (TextView)findViewById(id.Text); t.setText(contents); } }
呼び出される側のActivityで記述する内容例(参考もとのサイト)
AndroidManifest.xml内に記述
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="foo" android:mimeType="text/html" /> </intent-filter>
代表的な共通インテント実装の呼び出し(その他の詳細はここを参照)
// 明示的インテント(自分のアプリ内のActivityを起動) Intent intent = new Intent(this, xxx.xxx.xxx.class); //xxxにはパッケージのパスが入る // WEBブラウザ Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("http://www.gamvaro.com/kswiki/")); // 指定した緯度・経度の位置をGoogleマップで開く Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("geo:latitude,longitude")); // 指定した番号のダイヤル画面を表示する Intent intent = new Intent(Intent.ACTION_DIAL,Uri.parse("tel:03-1111-2222"));
androidでは、アプリの起動や利用しているOSの機能などを、AndroidManifest.xmlで記述している。そのため、アプリが最初に呼び出すActivityクラスもここで指定される。通常、Activityの追加には、このxmlに下記の様な行を追加する。
<application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".myAppMainActivity" android:label="@string/app_name"> </activity> </application>
このmyAppMainActivityが、ソースに記述されるActivityクラスを継承した、自分のActivityである。ここの自分の継承クラスを最初に呼び出す場合には、次の様に変更する
<application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".myAppMainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN"></action> <category android:name="android.intent.category.LAUNCHER"></category> </intent-filter> </activity> </application>
これは、自分のActivityが、上記の様にintentを受け付けることを宣言し、またそのActionとCategoryについて、MAINでLAUNCHする旨を記述することで、このActivityがアプリの起動時に呼び出される。
Androidでは、リソースについてプロジェクト単位で管理される。その為、多くのリソースを利用する場合には管理方法に注意する必要がある。リソースの利用方法は以下のように、R.raw.sample_movie など、「R.」をつける。これはandroidでは、プロジェクトの/resフォルダ以下を、/gen/R.java ファイルが自動的にresidとの関連付けを行ってくれる為。
また、システム画像などのリソースには、android.R.drawable.ic_menu_star などの指定方法を利用する。このシステムリソースを確認するには、android SDKをインストールしたフォルダの下の「android-sdk-mac_x86/platforms/android-7/data/res/drawable」の中を確認すれば良い。
item.setIcon( android.R.drawable.ic_menu_add );
※各フォルダ名はsdkのバージョンなどによって変化する点は注意。sdkのバージョンによって、システムリソースが違うため
Androidでは小さい画面での利用を強く意識している。
基本main.xmlファイル
<?xml version="1.0" encoding="utf-8"?> <LinearLayout> <TextView /> </LinearLayout>
この例では、1行目はお約束だが、2行目のLinearLayoutというタグが、レイアウトタイプを指定している。レイアウトタグには以下のようなタイプが存在する。
レイアウトタグ名 | 概要 |
FrameLayout | 主にフレームのレイアウト |
LinearLayout | 主にボタンなどのUIパーツを縦に並べるレイアウト方式。設定画面などに便利 |
RelativeLayout | |
TableLayout | テーブル形式のレイアウトなどに利用 |
AndroidでもiPhone Interface Builder(以下IB)を同じような、画面をレイアウトするツールが提供されている。ただIBと同じでダイナミックに作成されるビューにはあまり向いているとはいえず、デザイン変更などで分かりづらくなってしまうことが散見する。よって、設定ページや固定レイアウトのページでは効果的であるものの、一般的なアプリのメイン画面では使いづらいと思われる。
ちなみに、Javaの特性上、リソースを一切含まないプロジェクトであるなら、それをjarの形のライブラリにしておくことができるという情報もあり、配慮の必用がありそうだ。
androidでは、すべての機種にメニューボタンというものがついており、ここを押すことで対象となる画面のメニューがモーダルで現れるようになっている。ここのコードはActivityのメソッドで定義することでメニューの遷移を記述できる。
private static final int MENU_ITEM_ADD = 0; private static final int MENU_ITEM_SET = 1; // メニューボタンが最初に押された場合に呼ばれる @Override public boolean onCreateOptionsMenu( Menu menu ) { super.onCreateOptionsMenu(menu); MenuItem itemAdd = menu.add( 0, MENU_ITEM_ADD, 0, "Add" ); MenuItem itemSet = menu.add( 0, MENU_ITEM_SET, 1, "Seeting" ); itemAdd.setIcon( android.R.drawable.ic_menu_add ); itemSet.setIcon( android.R.drawable.ic_menu_preferences ); return true; } // メニューが表示された時に呼ばれる。 @Override public boolean onPrepareOptionsMenu( Menu menu ) { super.onPrepareOptionsMenu(menu); menu.findItem(MENU_ITEM_ADD).setEnabled(true); menu.findItem(MENU_ITEM_SET).setEnabled(false); return true; } // メニューが選択された時に呼ばれる。 @Override public boolean onOptionsItemSelected( MenuItem item ) { super.onOptionsItemSelected(item); if( item.getItemId() == MENU_ITEM_ADD ){ Log.d( "DEBUG_TEST", "code = MENU_ITEM_ADD" ); }else{ Log.d( "DEBUG_TEST", "code = MENU_ITEM_SET" ); } return true; }
Androidでは、複数のcpuに対応しているため、出来上がった apk には複数の cpu に対応したバイナリが作成できる。そのため、apk のバイナリ認識順番がパフォーマンスにも影響します。(例:arm7v の cpu なのに、arm5vのソースを優先ロードしてしまうなど)
<8桁のバージョンコードの解説>
第1桁:ABIの種類(1..arm5v, 2..arm7v, 6..x86) 第2~3桁:APIのバージョン(14, 21 などの API番号) 第4~5桁:スクリーンサイズ種別コード 第6~8桁:アプリのバージョン番号
Android Emulator や、実機とPCの接続では、adb というコマンドを利用するが、その際の端末に割り振られた情報を利用する場合以下のようなコマンドがある。
# adb shell ls /sys/class/net
また、上記の情報を元に割り振られたIPアドレスを確認するには、
# adb shell ifconfig eth0
emulatorなどでテストをする場合に、androidの仮想領域にデータを保存しておきたい場合がある。その場合には以下のコマンドでファイルをコピーすることができる。
adb push source_file.mp4 /data/source_file.mp4
これは、source_file.mp4 を、仮想領域の/dataフォルダにコピーする。また、コピーしたデファイルなどを削除する場合には、以下のコマンドで削除できる。
adb shell rm /data/source_file.mp4
基本的にandroidはLinuxで稼働していることから、adb shell コマンドを利用することで、androidのOSに対して、Linuxコマンドを発行できる。よってこのようなrmコマンドを利用することで、ファイルの削除ができる。
android開発環境にはDDMSというデバッグモニタが付いている。eclipseの「ウィンドウ -> パースペクティブを開く -> DDMS」でDDMSが起動する。上記のファイル操作なども、ここのFile Explolerを利用することで、マウスでファイルを操作することができる。またDDMSはアプリ(JavaVM)が起動されると、自動的にアプリとの通信用にポート8600番からを占有する。また、8700番はEclipseとの接続用に固定される。(下記写真を参照の事)
主な機能
DDMSのデバイスリスト画面
多くの開発においてLog出力は重要なデバッグ手法である。androidでも、Logコマンドを利用し、logcatにlog情報を出力できる。
Logの例
int x = 10; Log.d("MyApp", "x=" + x);
Logにはメソッドの指定によって、d=debug(デバッグ用、上記例ではこのdが指定されている), w=warning(注意), v=verbose(詳細), i=info(報告), e=error(エラー)という分類を指定できる。また第1引数には自分のアプリ名、第2引数にはLog文章を入れる。
Androidでは、なぜかMediaPlayerの利用ミスによる、バグによってThreadなどが停止してしまうバグが存在する。MediaPlayerのテストは十分かつ、念入りなテストと動作確認をしてから、本編に組み込み用に心がけた方が良いだろう。
Androidでは、adb shell コマンドを利用することで、実機にshellのログインができる。ここでTopコマンド利用することが多いと思うが、各項目は以下の通りと思われる。
項目名 | 説明 |
PID | プロセスID、DDMSのTIDと同じLinux上でのプロセス管理番号 |
CPU% | CPUの利用比率 |
S | プロセスのステータス。Rは実行可能,Sは停止,Dは割り込み不可の停止,Tは停止またはトレース中,Zはゾンビ・プロセス,Wはスワップ・アウトしたプロセス,Nはナイス値が正であることを表す |
#THR | スレッドの数、DDMSのThreads項目でその明細を確認できる |
VSS(virtual set size) | 使用している仮想メモリー量 |
RSS(resident set size) | 使用中の物理メモリー量 |
PCY | |
UID | ユーザーID、通常アプリケーションの場合は、app_xxという名前が割り振られる |
Name | アプリケーションのパッケージ名 |
Keystore name: debug.keystore Keystore password: android Key alias: androiddebugkey Key password: android CN (common name): CN=Android Debug,O=Android,C=US
通常はアプリケーションの名前が一番上に表示されるため少しだけ表示エリアが狭くなっている。このアプリ名表示エリアを消す方法。(onClickメソッド等に記述)
requestWindowFeature(Window.FEATURE_NO_TITLE);
ライブラリのプロジェクトを作成し、いろいろなアプリで共有したい場合は多いと思われる。その際には、以下の手順でAndroidプロジェクトを作成する。
※このライブラリ登録がされていないと、コンパイルがうまく行っても実行時に「Could not find xxxx class...」などのライブラリとして作成したクラスが見つからないエラーを表示してアプリが落ちる
Androidの機種情報は以下のコードで取得できる。
import java.lang.reflect.Field; Field[] fs = Build.class.getDeclaredFields(); for(Field f : fs){ f.setAccessible(true); String key = f.getName(); String name = f.get(null).toString(); }
このサイトでこのキーの概要について説明している。
また、機種毎のデバイス名などの詳細情報については、ここのページが詳しい。
Android SDKに含まれているトレースツールの使い方。Activityの本体に下記のソースを埋め込む。
onCreateメソッドの中の先頭に以下の行を追加
//プロファイリング開始 Debug.startMethodTracing("profile");
onDestoryメソッドの中の先頭に以下の行を追加
//プロファイリング終了 Debug.stopMethodTracing();
その後、Androidの実機からトレースデータを取得して表示
# adb pull /sdcard/patom.trace ./tmp/profile.trace # traceview ./tmp/profile.trace
Androidでは、NDKで作成したSOファイルの中身は、LinuxのELFファイルという形式で保存されている。そのため、ARMにあわせたreadelfコマンドが、android ndkで提供されており、以下のように指定することで、SOファイルの中を確認できる。 <登録されているダイナミック情報>
# arm-linux-androideabi-readelf -d libtest.so
<登録されているシンボル情報の一覧>
# arm-linux-androideabi-readelf -s libtest.so
<登録されているすべての情報>
# arm-linux-androideabi-readelf -a libtest.so
この readelf コマンドは、linuxのコマンドでありandroid用かつ各アーキテクチャ用の実行ファイルが存在する。
Androidでは、オープンソースで開発されているため、本体のソースコードを取得することができる。開発を行う上ではDebugの為や、勉強に為にソースを入れておくことを推奨する。
URL : http://android.git.kernel.org/?p=platform/manifest.git;a=summary # mkdir android-src # cd android-src # repo - init -u git://android.git.kernel.org/platform/manifest.git -b android-2.1_r2 # repo sync
※android-2.1_r2の部分は、自分が開発するSDKのバージョンに合わせてURLのページから取得する
※またrepoコマンドは、iPhone開発のページを参照の事
※上記のデータ取得が面倒な場合には、ここに纏めたものをおく
取得したデータからeclipseで利用できるようにファイルをコピーする
eclipseからandroidのソースをみれるようにするには、上記で作成された android-src のフォルダの中から、すべてのフォルダにおいて、srcフォルダ以下のソースを、android-sdkの中に入れ、eclipseを再起動するだけで、F3でandroid本体のソースがみれる。
%android-sdk-windows等%/platforms/android-7/sources/ <- このフォルダ以下に入れる。
arm-eabi-strip
キー | 機能 |
CTRL + Space | 入力中の単語の保管を行う。メソッド入力時はメソッドリストを表示 |
F3キー | 選択されているコマンドの定義ファイルにジャンプする |
F4キー | 型階層を開く |
F5キー | 最新の状態にする。主にプロジェクトにリソースを追加した時など(R.javaの更新) |
command + 1 | カーソル付近の単語の選択修正 |
command + / | 選択行をコメントアウトする。もう一度押すと解除 |
command + m | 選択中のビューを最大化する。もう一度押すと解除 |
command + w | 選択中のビューを閉じる。 |
command + e | エディットファイルの切り替え |
command + s | 選択しているファイルの保存 |
command + d | 選択している行を1行削除する |
command + f | 検索と置換 |
command + i | インデントの自動修正(便利) |
command + [ | ビュー移動を戻る |
command + ] | ビュー移動を進める |
command + z | undo |
command + option + q | 各種ビューを開く。選択ウィンドウが表示される |
command + option + j | カーソルのあるメソッドにJavaDocを元にコメントを追加 |
command + o | クイック・アウトライン。ファイルのアウトラインを表示 |
command + Shift + o | 不足しているimport分を選択で簡単追加 |
command + g | メソッドを呼び出している個所を検索し、検索ビューに表示 |
CTRL + h | クラス名を入力して、メソッドを呼び出している個所を検索し、検索ビューに表示 |
command + t | 型階層ウィンドウの表示 |
command + option + t | 該当メソッドを呼び出しているものを階層表示 |
command + option + r | リファクタリング。プロジェクト内に対して対象語を置換 |
Android Emulator (AVD)が起動しない
リソースを足したのに、R.javaが更新されない
androidでは、以下の条件の時に自動生成のはずのR.javaが更新されない。
.svnのファイルがプロジェクトに認識されwarningを出力してしまう
eclipseの「環境設定」->「Java」->「コンパイラー」->「ビルド」の中の、出力フォルダの左の矢印をクリックするとテキストボックスが出てくる。デフォルトでは「*.launch」のみだが,これを「*.launch, .svn」に変更することで解決する。
使っていないクラスのimport文を自動的に削除する
Eclipseの「環境設定」->「Java」->「Editor」->「保管アクション」を選択し、「保管時に選択したアクションを実施」と「インポートの構成」の二つをチェックする。
osxにEasyTetherをインストールするとadbがデバイスを認識しなくなる
Android開発時には、EasyTetherをOFFにする。
# sudo kextunload /System/Library/Extensions/EasyTetherUSBEthernet.kext
ONにする
# sudo kextload /System/Library/Extensions/EasyTetherUSBEthernet.kext
状態を見る
# kextstat |grep EasyTether
機種 | 製造 | CPU | Core数 | RAM | ROM | 解像度 | GPU | AndroidOS |
MEDIAS LTE N-04D | NEC | APQ8060 1.5Ghz | 2 | 1GB | 16GB | 1280x720 | Adreno 220 | 2.3 |
Galaxy S II LTE SC-03D | サムスン | APQ8060 1.5Ghz | 2 | 1GB | 16GB | 800x480 | Adreno 220 | 2.3 |
ARROWS X LTE F-05D | 富士通 | Cortex-A9 1.2Ghz | 2 | 1GB | 8GB | 1280x720 | PowerVR SGX540 304Mhz | 2.3.5 |
Optimus LTE L-01D | LG | APQ8060 1.5Ghz | 2 | 1GB | 4GB | 1280x720 | Adreno 220 | 2.3 |
ARROWS μ F-07D | 富士通 | MSM8255 1.4Ghz | 1 | 512MB | 1GB | 800x480 | Adreno 205 | 2.3.5 |
MEDIAS PP N-01D | NEC | MSM8255 1.4Ghz | 1 | 512MB | 2GB | 800x480 | Adreno 205 | 2.3 |
REGZA Phone T-01D | 東芝 | Cortex-A9 1.2Ghz | 2 | 1GB | 4GB | 1280x720 | PowerVR SGX540 304Mhz | 2.3 |
AQUOS Phone SH-01D | SHARP | Cortex-A9 1Ghz | 2 | 1GB | 1GB | 1280x720 | PowerVR SGX540 304Mhz | 2.3 |
GALAXY NEXUS SC-04D | サムスン | Cortex-A9 1.2Ghz | 2 | 1GB | 16GB | 1280x720 | PowerVR SGX540 384Mhz | 4.0 |
ARROWS kiss F-03D | 富士通 | MSM8255 1.4Ghz | 1 | 512MB | 1GB | 800x480 | Adreno 205 | 2.3 |
Q-pot.Phone SH-04D | SHARP | MSM8255 1GHz | 1 | 512MB | 2GB | 960x540 | Adreno 205 | 2.3 |
AQUOS PHONE slider SH-02D | SHARP | MSM8255 1GHz | 1 | 512MB | 2GB | 960x540 | Adreno 205 | 2.3 |
LUMIX Phone P-02D | Panasonic | OMAP4430 1GHz | 2 | 1GB | 2GB | 960x540 | PowerVR SGX540 304MHz | 2.3 |
P-01D | Panasonic | MSM8255 1GHz | 1 | 512MB | 1GB | 800x480 | Adreno 205 | 2.3 |
Xperia PLAY SO-01D | SONY | MSM8255 1GHz | 1 | 512MB | 1GB | 854x480 | Adreno 205 245MHz | 2.3.4 |
Xperia ray SO-03C | SONY | MSM8255 1GHz | 1 | 512MB | 1GB | 854x480 | Adreno 205 | 2.3 |
MEDIAS WP N-06C | NEC | MSM8255 1GHz | 1 | 512MB | 1GB | 854x480 | Adreno 205 | 2.3 |
Xperia acro SO-02C | SONY | MSM8255 1GHz | 1 | 512MB | 1GB | 854x480 | Adreno 205 | 2.3.3 |
GALAXY S II SC-02C | サムスン | Exynos 4210 1.2GHz | 2 | 1GB | 16GB | 800x480 | Mali-400 | 2.3 |
P-07C | Panasonic | OMAP3630 1GHz | 1 | 512MB | 1GB | 854x480 | PowerVR SGX530 | 2.3 |
F-12C | 富士通 | MSM8255 1GHz | 1 | 512MB | 1GB | 800x480 | Adreno 205 | 2.3.4 |
AQUOS PHONE f SH-13C | SHARP | MSM8255 1GHz | 1 | 512MB | 2GB | 960x540 | Adreno 205 | 2.3.4 |
Optimus bright L-07C | LG | OMAP3630 1GHz | 1 | 512MB | 2GB | 800x480 | PowerVR SGX 530 | 2.3 |
AQUOS PHONE SH-12C | SHARP | MSM8255T 1.4GHz | 1 | 512MB | 2GB | 960x540 | Adreno 205 | 2.3 |
Xperia arc SO-01C | SONY | MSM8255 1GHz | 1 | 512MB | 1GB | 854x480 | Adreno 205 | 2.3 |
MEDIAS N-04C | NEC | MSM7230 800MHz | 1 | 512MB | 1GB | 854x480 | Adreno 205 | 2.2 |
Optimus chat L-04C | LG | MSM7227 600MHz | 1 | 512MB | 1GB | 480x320 | Adreno 200 | 2.2 |
REGZA Phone T-01C | 東芝 | QSD8250 1GHz | 1 | 512MB | 1GB | 854x480 | Adreno 200 | 2.1 |
LYNX 3D SH-03C | SHARP | QSD8250 1GHz | 1 | 512MB | 1GB | 800x480 | Adreno 200 | 2.1 |
GALAXY S SC-02B | サムスン | S5PC110 1GHz | 1 | 512MB | 512MB | 800x480 | PowerVR SGX540 | 2.2 |
LYNX SH-10B | SHARP | QSD8250 1GHz | 1 | 512MB | 4GB | 960x480 | Adreno 200 | 1.6 |
Xperia SO-01B | SONY | QSD8250 1GHz | 1 | 384MB | 1GB | 854x480 | Adreno 200 | 1.6 |
HT-03A | HTC | MSM7201a 528MHz | 1 | 192MB | 512MB | 480x320 | none | 1.5 |
GALAXY Tab SC-01C | サムスン | S5PC110 1GHz | 1 | 512MB | 512MB | 1024x600 | PowerVR SGX540 | 2.2 |
機種 | 製造 | CPU | Core数 | RAM | ROM | 解像度 | GPU | AndroidOS |
INFOBAR A01 | SHARP | MSM8655T 1.4GHz | 1 | 512MB | 1.1GB | 960x540 | Adreno 205 | 2.3 |
IS-03 | SHARP | QSD8650 1GHz | 1 | 512MB | 512MB | 960x640 | Adreno 200 | 2.1 |
REGZA Phone IS-04 | 富士通 | QSD8650 1GHz | 1 | 400MB | 1GB | 854x480 | Adreno 200 | 2.1 |
IS-05 | SHARP | MSM8655 1GHz | 1 | 512MB | 512MB | 854x480 | Adreno 205 | 2.2 |
SIRIUS α IS-06 | P&C | QSD8650 1GHz | 1 | 512MB | 512MB | 800x480 | Adreno 200 | 2.2 |
Evo WiMAX ISW11HT | HTC | QSD8650 1GHz | 1 | 512MB | 1GB | 800x480 | Adreno 200 | 2.2 |
Xperia acro IS11S | SONY | MSM8655 1GHz | 1 | 512MB | 1GB | 854x480 | Adreno 205 | 2.3 |
AQUOS PHONE IS11SH | SHARP | MSM8655T 1.4GHz | 1 | 512MB | 2GB | 960x540 | Adreno 205 | 2.3 |
G'zOne IS11CA | NEC | MSM8655 1GHz | 1 | 512MB | 1GB | 800x480 | Adreno 205 | 2.3 |
AQUOS PHONE IS12SH | SHARP | MSM8655T 1.4GHz | 1 | 512MB | 2GB | 960x540 | Adreno 205 | 2.3.3 |
REGZA Phone IS11T | 東芝 | MSM8655T 1.4GHz | 1 | 512MB | 1GB | 854x480 | Adreno 205 | 2.3.4 |
Evo 3D ISW12HT | HTC | MSM8660 1.2GHz | 2 | 1GB | 4GB | 960x540 | Adreno 220 | 2.3.4 |
MOTOROLA PHOTON ISW11M | Motorola | Tegra250 1GHz | 2 | 1GB | 16GB | 960x540 | ULP GeForce GPU (Tegra2 AP20H)(Tegra250) | 2.3.4 |
AQUOS PHONE IS13SH | SHARP | MSM8655T 1.4GHz | 1 | 512MB | 4GB | 960x540 | Adreno 205 | 2.3.5 |
MEDIAS BR IS11N | NEC | MSM8655T 1.4GHz | 1 | 512MB | 2GB | 800x480 | Adreno 205 | 2.3.5 |
MIRACH IS11PT | P&C | MSM8655 1GHz | 1 | 512MB | 1GB | 800x480 | Adreno 205 | 2.3 |
DIGNO ISW11K | 京セラ | MSM8655T 1.4GHz | 1 | 1GB | 4GB | 800x480 | Adreno 205 | 2.3.5 |
ISW11F | 富士通 | OMAP4430 1.2GHz | 2 | 1GB | 8GB | 1280x720 | PowerVR SGX540 304MHz | 2.3.5 |
機種 | 製造 | CPU | Core数 | RAM | ROM | 解像度 | GPU | AndroidOS |
AQUOS PHONE 102SH | SHARP | OMAP4430 1GHz | 2 | 1GB | 2.2GB | 1280x720 | PowerVR SGX540 304MHz | 2.3 |
AQUOS PHONE 104SH | SHARP | OMAP4460 1.5GHz | 2 | 1GB | - | 1280x720 | PowerVR SGX540 384 MHz | 4.0 |
LUMIX Phone 101P | Panasonic | OMAP4430 1GHz | 2 | 1GB | 2GB | 960x540 | PowerVR SGX540 304 MHz | 2.3 |
HONEY BEE 101K | 京セラ | MP5225 1.2GHz | 2 | 512MB | 1.5GB | 800x480 | PowerVR SGX543 MP | 2.3 |
AQUOS PHONE 101SH | SHARP | MSM8255 1GHz | 1 | 512MB | - | 854x480 | Adreno 205 | 2.3 |
AQUOS PHONE 103SH | SHARP | MSM8255T 1.4GHz | 1 | - | - | 960x540 | Adreno 205 | 2.3 |
STAR7 009Z | ZTE | MSM8255 1GHz | 1 | 512MB | 4GB | 800x480 | Adreno 205 | 2.3 |
MEDIAS CH 101N | NEC | MSM8255T 1.4GHz | 1 | - | - | 800x480 | Adreno 205 | 2.3 |
STREAK PRO 101DL | DELL | MSM8260 1.5GHz | 2 | 1GB | 8GB | 960x540 | Adreno 220 | 2.3 |
AQUOS PHONE 007SH | SHARP | MSM8255 1GHz | 1 | 512MB | 2GB | 854x480 | Adreno 205 | 2.3 |
AQUOS PHONE 006SH | SHARP | MSM8255T 1.4GHz | 1 | 512MB | 2GB | 960x540 | Adreno 205 | 2.3 |
AQUOS PHONE 009SH | SHARP | MSM8255 1GHz | 1 | 512MB | 1GB | 960x540 | Adreno 205 | 2.3 |
Sweety 003P | Panasonic | OMAP3630 1.0GHz | 1 | 512MB | 1GB | 854x480 | PowerVR SGX530 | 2.3 |
Vision 007HW | Huawei | MSM8255 1GHz | 1 | 512MB | 2GB | 800x480 | Adreno 205 | 2.3 |
シンプルスマホ 008Z | ZTE | MSM8255 1GHz | 1 | 512MB | 4GB | 800x480 | Adreno 205 | 2.3 |
GALAPAGOS 003SH | SHARP | MSM8255 1GHz | 1 | 512MB | 1GB | 800x480 | Adreno 205 | 2.2 |
GALAPAGOS 005SH | SHARP | MSM8255 1GHz | 1 | 512MB | 1GB | 800x480 | Adreno 205 | 2.2 |
Libero 003Z | ZTE | MSM7227-1 600MHz | 1 | 512MB | 115MB | 800x480 | Adreno 200 | 2.2 |
機種 | 製造 | CPU | Core数 | RAM | ROM | 解像度 | GPU | OS version |
iPhone4S | Apple | Apple A5 800MHz | 2 | 512MB | 16GB-64GB | 960x640 | PowerVR SGX543MP2 | iOS 5 |
iPhone5 | Apple | Apple A6 | 2 | 1GB | 16GB-64GB | 1136x640 | PowerVR SGX543MP3 | iOS 6 |
iPhone5s | Apple | Apple A7 | 2 | 1GB | 16GB-64GB | 1136x640 | PowerVR G6430 | iOS 7 |
iPad 4th | Apple | Apple A6X | 2 | 1GB | 16GB-64GB | 2048x1536 | PowerVR SGX554MP4 | iOS 6 |
iPad Mini | Apple | Apple A5 | 2 | 512MB | 16GB-64GB | 1024x768 | PowerVR SGX543MP2 | iOS 6 |
※APQとMSMはQualcomm社製。CortexはARM社製。OMAPはTexas Instruments社製。ExynosとS5PC110はサムスン社製(ベースはARM)。ZTEは中国の会社。
QVGA | 240x320 | Tatoo, Xperia mini |
HVGA | 320x480 | G1, HT-03A, GDD Phone, Optimus chat(L-04C) |
WVGA | 480x800 | Nexus One, HTC Desire, LYNX 3D(SH-03C), GALAXY S(SC-02B), SIRIUS α(IS06), htc EVO WiMAX(ISW11HT) |
FWVGA | 480x854 | Droid, Xperia, IS01, IS05, Xperia arc(SO-01C), MEDIAS(N-04C), REGZA Phone(T-01C,IS04) |
FWVGA | 960x480 | LYNX(SH-10B) |
DVGA | 960x640 | IS03(au) |
WSVGA | 600x1024 | GALAXY Tab(SC-01C) |
WXGA | 1280x768 | Optimus Pad(L-06C) |
1280x800 | MOTOROLA XOOM(TBi11M) |
画面の大きさ(size) | 記述(res/layout) |
small | res/layout-small |
normal | res/layout-normal |
large | res/layout-large |
密度の違い(Density Per Inch) | 記述(res/drawable) |
high(190〜250dpi:基準240dpi) | res/drawable-hdpi |
midium(140〜180dpi:基準160dpi)) | res/drawable-mdpi |
low(100〜140dpi:基準120dpi) | res/drawable-ldpi |
dpi に関係なく使用する画像を保存する場合 | res/drawable-nodpi |
参考ソース
/* DIPとピクセルの変換 */ mMetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(mMetrics); scaleDensity = mMetrics.scaleDensity; pixcels = dips * scaleDensity; /* 画面サイズの取得ソースコード */ Display display = getWindowManager().getDefaultDisplay(); int height = display.getHeight(); int width = display.getWidth(); /* Supports-Screensの記載例 */ <supports-screens android:largeScreens="true" android:normalScreens="true" android:lSmallcreens="true" android:andDensity="true" /> <uses-sdk android:minSdkVersion="4" />
メーカー | 機種名(型番) | Total | CPU | Mem | I/O | 2D | 3D |
Samsung | SC-02D | 3068 | 4724 | 3843 | 3944 | 990 | 1839 |
SC-03D | 3722 | 5740 | 2878 | 7105 | 667 | 2220 | |
SC-04D | 1929 | 5415 | 1854 | 1062 | 196 | 1119 | |
Sony | SO-01D | 1176 | 1950 | 1392 | 916 | 298 | 1326 |
SO-02D | 2262 | 4311 | 1643 | 3526 | 230 | 1602 | |
富士通 | F-03D | 1505 | 2753 | 1408 | 1247 | 388 | 1727 |
Eclipseの全体のPreferencesに、Androidタグのあるので、その中のDDMSの項目の中に、ADB connection timeoutという項目があるので、その時間を5000から20000などの長い時間に変更する。
AndroidManufest.xml のパッケージ名など、パッケージに関する設定がおかしい場合に発生する。
Androidでは、SurfaceViewの継承クラスが複数あるような場合、SurfaceFlingerというOSの上に直結した特殊な画面合成レイヤーが存在し、それらが複数のSurfaceの描画順を、内部のZ値(深度)を元に処理を行うが、Z値がシーン切り替えなどの画面に変化があったときに、再度、それぞれのSurfaceに動的に値が設定されるが、その値は同一のActivity内のSurfaceの場合、適当になるという恐ろしいバグのような仕様がある。そこで、onCreateを代表する、onSuspendやonResumeなどすべての画面変化があるタイミングで、一番上になるSurfaceに対して、SurfaceView.setZOrderOnTop(true); という形でZを強制的にTOPする機能を使い表示順を調整する必要がある。
GLSurfaceViewは特殊なSurfaceViewであり、通常のSurfaceView用の、SurfaceHolder.callback関数として登録するべき、surfaceCreatedやsurfaceChangedなどは、Render登録をしたクラスの中に、onSurfaceCreatedや、onSurfaceChangedなどという名前に変更して登録する必要がある。ただしsurfaceDestroyedは、Renderでは定義できない為、GLSurfaceViewのメソッドとして登録する必要がある。
※もし、GLSurfaceViewにも、Renderクラスにも、surfaceCreatedの関数を両方に記述した場合、Renderのクラスで定義されたonSurfaceCreatedなどは、呼び出されない。ただし、そのメソッド内で、super.surfaceCreated(holder)のように、superクラスに転送を行うと、無事にRenderのonSurfaceCreatedにもイベントが届く。
上記の項目とも関係するが、GLSurfaceViewのメソッドに記述する、surfaceDestroyedメソッドは、特殊でこのメソッドの最後に、super.surfaceDestroyed(holder); という形で、superクラスのメソッドを呼ぶことで、Renderの破棄を行うのため、必ず指定すること。
自分のプログラムではなく、AndroidOSの内部で落ちるようなバグの場合、基本的にはスレッドによる問題である場合が多い。タイマースレッドやOpenGLのスレッド内から、UI関係の処理(SurfaceViewなどへの描画処理が多い)を行うような場合に発生する。このような場合は、Handlerクラスを用いて、UIスレッド(メインスレッド)で行わなくてはならない処理を、通知して実行させる必要がある。
シェルを起動し、ターミナルのエンコードを、SHIFT-JIS に変更後以下のコマンドを実行する。(passwordは 'android' )
keytool -genkey -v -keystore debug.keystore -alias androiddebugkey -keyalg RSA -validity 10000 -dname "CN=Android Debug,O=Android,C=US"
できあがった debug.keystore を、eclipseの設定->Android->Buiildに書かれている、default keystoreの場所のdebug.keystoreに上書きする。
また、すでにテストしていたアプリはuninstallしてから、テストするようにする。
どうやらAndroidのNativeでのmallocとfreeは特殊なようだ。mallocやfreeの対象となるシステム上のヒープ領域は、実際、Dalvik管轄下でGC(ガーベージコレクション)と連動されている。そのため、基本的にはmallocすると新規の領域が確保され、freeした場合には解放されるべき領域として解放待機に入る。これはメモリの使用量などを表示すると、一見無尽蔵に確保されつづけ、一定の量になるとgcは発動して未使用領域を解放する。
多くのメーカーのAndroidのNative実装の部分においては、メモリ管理が機種によって微妙に異なっており、問題となる。Xperiaでも、他のメーカーのものと同じように、DalvikのGCとの連携をはかってはいるのだが、System.gc()のように、明示的にGCを起動させないと、Nativeメモリの解放が行われない。そのため、この点を意識せずに作ると長時間稼働などで落ちる。
サウンドなどハードに依存しそうな機能も当然ながら機種依存となる。特にmp3などの圧縮フォーマットへの対応や、ギャップレス対応など、millisecond単位の再生位置指定の正確性などは、典型的な部分となる。特にサウンドなどは、JNIのC言語ライブラリで、ハードを直接たたき、CPUの複数コアを利用したマルチスレッドになっている場合も多く、非常に複雑なため、メーカー毎の差が出やすい。
GPU名称 | 圧縮テクスチャー |
Mali-400 | ETC1 |
特にスプライト系(四角い画像の描画)の描画は以下の順で速度が違う。
処理方法 | 早さ |
基本的描画:vertex arraysを利用 | 遅い |
VBOを使って、頂点情報の再利用 | 早い |
DrawTextureExtensionを利用して描画 | 一番早い |
OpenGLの機能 | Type-A | Type-B |
OES_rgb8_rgba8 | ○ | ○ |
OES_fbo_render_mipmap | ○ | ○ |
OES_compressed_ETC1_RGB8_texture | ○ | ○ |
OES_EGL_image | ○ | ○ |
OES_EGL_sync | ○ | × |
OES_EGL_image_external | ○ | × |
OES_mapbuffer | ○ | × |
OES_vertex_half_float | ○ | ○ |
OES_vertex_type_10_10_10_2 | × | ○ |
OES_texture_half_float | ○ | ○ |
OES_texture_float | ○ | ○ |
OES_texture_3D | × | ○ |
OES_texture_half_float_linear | × | ○ |
OES_texture_npot | × | ○ |
OES_depth_texture | × | ○ |
OES_depth24 | × | ○ |
OES_element_index_uint | × | ○ |
OES_fragment_precision_high | × | ○ |
OES_get_program_binary | × | ○ |
OES_packed_depth_stencil | × | ○ |
OES_standard_derivatives | × | ○ |
EXT_Cg_shader | ○ | × |
EXT_packed_float | ○ | × |
EXT_texture_array | ○ | × |
EXT_texture_compression_latc | ○ | × |
EXT_texture_compression_dxt1 | ○ | × |
EXT_texture_compression_s3tc | ○ | × |
EXT_texture_filter_anisotropic | ○ | ○ |
EXT_bgra | ○ | × |
EXT_texture_format_BGRA8888 | ○ | ○ |
EXT_unpack_subimage | ○ | × |
EXT_texture_type_2_10_10_10_REV | × | ○ |
NV_fence | × | ○ |
NV_platform_binary | ○ | × |
NV_depth_nonlinear | ○ | × |
NV_draw_path | ○ | × |
NV_texture_npot_2D_mipmap | ○ | × |
NV_framebuffer_vertex_attrib_array | ○ | × |
NV_coverage_sample | ○ | × |
NV_get_tex_image | ○ | × |
NV_read_buffer | ○ | × |
NV_shader_framebuffer_fetch | ○ | × |
NV_fbo_color_attachments | ○ | × |
ARB_draw_buffers | ○ | × |
QCOM_driver_control | × | ○ |
QCOM_perfmon_global_mode | × | ○ |
QCOM_extended_get | × | ○ |
QCOM_extended_get2 | × | ○ |
QCOM_tiled_rendering | × | ○ |
QCOM_writeonly_rendering | × | ○ |
QCOM_memory_monitor | × | ○ |
AMD_compressed_3DC_texture | × | ○ |
AMD_compressed_ATC_texture | × | ○ |
AMD_performance_monitor | × | ○ |
AMD_program_binary_Z400 | × | ○ |
Type-A | NVIDIA Tegra(Motorola Xoom) |
Type-B | Qualcomm Adreno(Nexus One) |
NDKで作成される、.a や .so ファイルは、コンパイラに自動的に「-fPIC」オプション(position-independent codeの事)が指定され、再リンクが可能な形になっている。
gcc のオプション指定で、-mfpu=neon -mfloat-abi=softfp の両方を指定しないとneon稼動しない。
# adb shell pm list package
sdk>/tools/ant/build.xml で apk にインストールされる。 key.stone の場所は、主に c:\User\<user>\.android\key.stone
# jarsigner -verify -verbose -certs my_application.apk
以前にインストールした apk と、これからインストールする apk の証明書が違うため、一度、以前にインストールした apk をアンインストールする。
また、apk をアンインストールしても、エラーになる場合は、デバイスの下記フォルダを消す。
/data/data/<アプリケーション名> /data/app/<アプリケーション名>