WebアプリとAndroidアプリのアナロジー (「Androidのアレは,Webで例えるなら○○だ」)
Webアプリの開発者が,初めてAndroidアプリを作るとする。
Android SDKの使い方など,新しく覚える事が多い。
学習には時間がかかる。
そこで,効率的に学ぶため,
Webを使った「例え話(アナロジー)」で覚えてみるのはどうか?
- 「Webでいうとinput要素のテキストボックスを使うけど,あれはね,Androidでは『EditText』というViewだよ」
- 「Webアプリでは,GETとかPOSTで情報を持ちまわるでしょ。あれと同じ事をしたい場合,Androidでは,IntentというオブジェクトにputExtra()して,情報を詰め込んで次のActivityに渡せばいいんだよ」
みたいに。
もし,「Web ⇔ Android のポイントを,わかりやすく比較した一覧表」があれば,非常に役立つはずだ。
特に入門段階において,
Androidアプリのおおまかな基本構造をまず知りたい,という場合,
既存の知識との類似点・共通点をベースにして説明されたほうがわかりやすい。
いわば,「Webアプリ開発からの逆引き Android辞典」があればよい。
下記に,そのような一覧表を掲載する。
目次
- (1)画面の概念
- (2)画面遷移の概念
- (3)画面遷移時の情報の持ち回り
- (4)DOMのような概念
- (5)画面部品やUI
- (6)デザイン
- (7)画面のレイアウト
- (8)アーキテクチャ
- (9)ビルドとデプロイ
- (10)サンプルコードの比較
比較用の一覧表
WebアプリとAndroidアプリのアナロジー |
|
---|---|
Webアプリ | Androidアプリ |
(1)画面の概念 | |
URL | アクティビティ |
HTML+CSSファイル | レイアウト定義XML (R.layoutクラスのメンバ) |
HTMLタグ,画面部品 | ビュー(ウィジェット) |
サイトマップ | AndroidManifest.xml |
サイトのTOPページ | android.intent.action.MAIN と 指定されたアクティビティ |
window.close(); (ブラウザを閉じる) |
アクティビティ.finish(); |
onloadイベントからonunloadまでの HTMLページのライフサイクル |
onCreateからonDestroyまでの アクティビティのライフサイクル |
ページ内のペイン枠構造 またはフレーム |
Fragment (3系SDK以降,タブレット対応用) |
(2)画面遷移の概念 | |
formのsubmitや, aタグによるジャンプ |
startActivity |
HTTPリクエストのパケット本体 | インテント,Bundle |
Ajaxによる同一画面内での 動的な表示切り替え |
同一アクティビティ内での 複数回のsetContentView(), またはインフレート |
ブラウザの戻るボタン | 端末のBACKボタン |
パケットのブロードキャストによる サーバの特定と通信開始 |
暗黙的インテント |
受信したブロードキャストの パケットフィルタリング |
インテントフィルタ |
ネットワークの監視 | ブロードキャストされたインテントの 受信指定 |
(3)画面遷移時の情報の持ち回り | |
form内のinput要素 (HTTP送信用の情報) |
インテントへのputExtra |
サーバ側で受信した HTTPリクエストの 特定のパラメータの値 |
getIntent().getExtras().getString(キー) |
アプリ利用中,画面をまたいで情報を保管 (サーバ上のsessionデータ) |
staticなクラスのフィールドに保管 |
アプリ利用終了後もアプリ内に情報を保持 (データの永続化) |
SQLiteでDB書き込み |
キー・バリュー・ストア で永続化 |
プリファレンス |
複数アプリでDB共有 | コンテンツリゾルバを介して コンテンツプロバイダと通信 |
(4)DOMのような概念 | |
getElementById | findViewById |
DOMツリー | R.idクラス |
window (または,リファラなどを含む 「ブラウザの現在の状態」全て) |
Context |
window.alert() | AlertDialog |
WSHのWshShellオブジェクトの popupメソッド (一定時間で消える) |
Toast (画面遷移しても一定時間表示され続ける) |
このページのスクプトは 処理に時間がかかっているか、 応答しなくなっています |
ANRダイアログ |
(5)画面部品やUI | |
リテラル(文字列べた書き) | TextView |
文言やメッセージの 定義ファイル (getTextによる国際化など) |
strings.xml |
getTextで文言取得 _("メッセージID") |
アクティビティのインスタンス .getResources() .getString( R.string.メッセージID ) |
input要素(type="text") | EditText |
type="text"であるようなinput要素の value="〜〜" |
android:text="@string/リソース名" |
selectタグとoption要素 | Spinnerとエントリー配列 |
プルダウン要素.options[ プルダウン要素.selectedIndex ].text | スピナーオブジェクト.getSelectedItem().toString() |
プルダウン要素.selectedIndex (0始まり) |
スピナーオブジェクト.getSelectedItemPosition() (0始まり) |
multiple属性付きの selectメニュー |
ListView |
nameが同一の 複数のラジオボタン |
RadioGroup内の 複数のRadioButton |
imgタグのalt属性のような ツールチップ表示 |
マウスカーソルという概念が 無いので,Toastで代用 |
input要素のdisabled属性 による無効化 |
ViewにsetEnabled(false)か android:clickable="false"指定 |
(6)デザイン | |
各タグにstyle属性を 個別に直書き |
レイアウトXML内で, 各タグに属性を直書き |
cssファイル | テーマ |
特定のCSSクラスを適用した要素 | Viewをextendした独自クラス |
style="font-weight:bold" | android:textStyle="bold" |
color | textColor |
height | layout_height |
margin-bottom | layout_marginBottom |
padding-left | paddingLeft |
font-size | textSize |
画面上の要素の可視性について, visibility:hiddenとdisplay:noneの違い |
ViewのsetVisibilityで View.INVISIBLEとView.GONEの違い |
background-repeat:repeat で 背景を縦横に繰り返し |
android:background属性のXMLで bitmapにtileMode="repeat" ※repeat-xやrepeat-yは別途 |
(7)画面のレイアウト | |
内部でdiv要素が 縦に並ぶコンテナ要素 |
LinearLayout(Vertical) |
内部でdiv要素(float:left)が 横に並ぶコンテナ要素 |
LinearLayout(Horizontal) |
align="center" のdiv要素 | gravity="center_horizontal"の レイアウトビュー |
vertical-align="middle" のdiv要素 | gravity="center_vertical"の レイアウトビュー |
float:rightの要素 | RelativeLayout中で, layout_alignParentRight="true" と指定された要素 |
overflow-y:scrollのdiv要素 (疑似フレーム) |
ScrollView→LinearLayout→複数要素 という親子関係 |
width="*" で 「残り全部」という幅指定 |
android:layout_weight="1" |
画面共通部品の読み込み | includeタグ |
(8)アーキテクチャ | |
Windows, Linux等のOS (各種ドライバを含む) |
Android OS (カーネルはLinux2.6) |
OSのバージョン | Platform Version |
ミドルウェア類 (DB,グラフィクスエンジンなど) |
「標準ライブラリ」 (C, C++で実装) |
アプリケーション実行環境 (インタプリタ+コアライブラリ等) |
「Androidランタイム」 (Dalvik VM+J2SE5.0) |
1アプリケーションのための APサーバのプロセス |
Dalvik VMの 1インスタンスプロセス |
アプリケーション実装時に利用するAPI | Android SDK (Javaで実装) |
APIのバージョン | Android SDK Level |
VMWareのゲストOS | AVD(エミュレータ) |
VMWareのゲストOSへの vmrunやSSH経由での操作 |
adb(デバッガツール) |
バッチ処理 | Serviceアプリ |
OS起動時に自動開始する サービスやデーモン |
BOOT_COMPLETEDに応答する ブロードキャストレシーバー |
タスクトレイ常駐アプリの 情報通知バルーン |
ノーティフィケーション |
データセンタが停電, UPSも使い切った |
バッテリー切れ |
(9)ビルドとデプロイ | |
バイトコードなどの 実行可能ファイル |
dexファイル (Dalvikバイトコード) |
クロスコンパイラ等 | Platform Tools |
実行可能ファイルのパッケージ (jarやwar) |
APKファイル |
デプロイ用の物理的なPC | 実機,端末本体 |
アプリケーションのデプロイ | マーケットへの公開 |
Seleniumで自動テスト | NativeDriverで自動テスト |
※入門用のアナロジーなので,厳密な対応ではない。
以下は,この一覧表の補足事項。
(1)画面の概念
AndroidManifest.xmlは「サイトマップ」に例えられるので,記載する画面の抜け・漏れがあってはならない。
Androidアプリ開発初心者がつまずきやすい7のポイント
http://www.dm-android.com/column/begg...
- 新しい画面を作成した時、マニフェストファイルに記述を加えなければ、エラーが表示されてしまいます
- 初心者は何故このエラーが出るか分からず、立ち往生してしまう場合があるようです
(2)画面遷移の概念
- HTMLのaタグは,れっきとした「GETリクエスト発行機」である。
- Ajaxについて
- 画面遷移:ひとつのアクティビティ内でリソースを切り替える方法
- http://d.hatena.ne.jp/androiddev/20110209/1297254242
- 暗黙的インテントについて:
ブロードキャスト:
- ブロードキャスト的なintentを受け取ることを宣言することによって、システムの監視ができる
- http://www.次世代創造機構.jp/android/androidLecture/Intent2/Intent2.html
(4)DOMのような概念
Contextとは何か:
Contextとは?
http://individualmemo.blog104.fc2.com...
- アプリケーションの環境情報とか「アプリ全体の状態」を持っていて、何から起動されたかどういう状態か、何にアクセスしようとしているか、といった情報を受け渡すために使う
- ContextにはActivity と Applicationの2つがある
(5)画面部品やUI
要素の有効化/無効化の切り替えについて(ボタンを押せなくするとか)
layout - How to disable an Android button?
http://stackoverflow.com/questions/43...
- myButton.setEnabled(false);
- android:clickable. you can't enable or disable it in xml but you can set it clickable
HTMLリファレンス:disabled=disabled - 無効化
http://www.tohoho-web.com/html/attr/d...
- disabled属性を指定した要素を無効化します。正確には disabled=disabled と書きますが、単に disabled と指定しても構いません
imgのaltのようなものについて:
AndroidアプリにおけるToolTip(ツールチップ)、ヘルプ表示に適したView(ビュー)
http://android.roof-balcony.com/view/...
- Windows用のアプリでは,ボタン等のコントロールにマウスカーソルを当てた状態で数秒放置すると、ヘルプメッセージが小さく表示される。これを、ToolTip(ツールチップ)と呼ぶ
- HTMLでも、イメージやリンク文字列等にマウスカーソルを当てた状態で数秒放置すると、ヘルプメッセージが小さく表示されるものがある。これは、例えば画像だと、ImageタグのALT属性に設定した文言が表示される
- Androidアプリでも簡単なヘルプメッセージを数秒間だけパッと表示させる、という場合に適したView(ビュー)がある。これが、Toast
(7)画面のレイアウト
layout_weightとは何かについて,詳しい説明:
Android SDK で, LinearLayout の動作を確認してみた.
http://noritan-micon.blog.so-net.ne.j...
- 余った部分いっぱいに子部品を広げたいこともあるでしょう.そんな時には, weight 属性で,「どの部品に残り部分を占有させたいか.」を指定することができます
- 占有する領域の広さは, weight に指定した値に比例する
LinearLayout の width(またはheight) と weight の関係
http://zaki.tdiary.net/20110702.html
- LinearLayout を使用する際、「とりあえず中の View の attribure に android:layout_weight="1" と書いとけばなんとなくうまくいく」なんてことを言われる場合があるが,よく理解して使わないとハマる
- View の幅を 1:2:3 にしたいしたい時はどうすればいいか
(8)アーキテクチャ
正確なアーキテクチャ図
Android SDKは「フレームワーク」という呼び名が付される事があるけども,
実際には単なる「API」に過ぎず,実用上の「フレームワーク」とは呼べない件について:
Android フレームワークとか
http://ksoichiro.blogspot.com/2011/05...
- 入門書やWebの情報を参考に作成していると、同じようなコードを何度も書くようでうんざりしてきます…
- Androidのフレームワーク、ライブラリなどはないのでしょうか?
- Android SDK自体、フレームワークなのですが一般的なWebアプリケーション等と同様、多数の入力画面やBean的なものを書こうとするとどうしても,入力チェック・DBアクセスのような部分が面倒に感じます
Androidアプリの開発用フレームワークは,一応マイナーながら存在する。
しかし,いずれもJavaScriptベースのライブラリであって,Javaベースの物の出現が望まれる。(2011/8現在)
例えば「Android on Rails」とか「Android Grails」のようなものが切実に欲しい。
HTML+JavaScriptでiPhone/Androidアプリを作れるTitanium Mobile
http://www.atmarkit.co.jp/fsmart/arti...
iPhoneやAndroid向けのJavaScriptフレームワーク・Wink Toolkitが割と良かったので日本語サンプル作った
http://kachibito.net/software/wink-to...
Android上で既存のJavaフレームワークが使えるかという話題も出ている:
Is Hibernate an overkill for an Android application?
http://stackoverflow.com/questions/42...
- HibernateやiBatisは重過ぎる&大きすぎるので,ORMLiteを使うべし。実績多数
ActiveAndroid
https://www.activeandroid.com/
- ActiveRecord風のコードをAndroidで書けるフレームワーク
Spring Android Framework
http://www.springsource.org/spring-an...
- Spring Android is an extension of the Spring Framework that aims to simplify the development of native Android applications.
以上で,一覧表の解説は終わり。
以下では,個別の項目単位ではなく,ソースコード単位で比較してみる。
(10)サンプルコードの比較
ボタンクリック時のイベントを定義
Web:
// ボタンクリック時のイベントを定義 ボタン要素.onclick = function(){ 〜クリック時の処理〜 };
Android:
// ボタンクリック時のイベントを定義 ボタン要素.setOnClickListener(new OnClickListener() { public void onClick(View v) { 〜クリック時の処理〜 } });
JavaScriptと違い,「onClick」と3回書く必要がある。
とはいえ,このように無名クラスを使って記述すれば,イベントとしてまるでクロージャを渡しているかのような気分は味わえる。
そもそもJDK1.1以降,Javaに匿名内部クラスが導入された本来の目的も,クロージャをエミュレートする事だ。
関数型の考え方: 関数型の観点で考える、第 1 回
http://www.ibm.com/developerworks/jp/...
- Java での振る舞いはすべて、クラス内部に含まれていなければなりませんが、Java 言語の設計者たちでさえも、この設計の不備にはすぐに気付きました。後から考えれば、クラスにアタッチされていない振る舞いはあり得ないと考えるのは、少し浅はかです。
- JDK 1.1 ではこの欠陥を是正するために、匿名内部クラスが追加されました。これにより少なくとも、ほんのわずかなメソッド (構造的ではない純粋な関数) で多数の小さなクラスを作成するための構文糖が提供されました。
- クラス自体が提供するメリットは何もなく、フィールドもなければ、(Java が自動生成するコンストラクターを別にすると) コンストラクターも状態も一切ありません。クラスはただ単に、振る舞いをメソッドの中に含めるラッパーとして機能します。
本物のクロージャは,Java 8 をお楽しみに。
クロージャなどが先送りされた「Java 7リリース計画」発表(2010年10月)
http://gihyo.jp/dev/clip/01/orangenew...
- Java 8へと先送りになってしまった主な機能:ラムダ式(クロージャ)の導入
クロージャからProject Lambdaへ (2010年3月)
http://itpro.nikkeibp.co.jp/article/C...
- クロージャをタスクとして扱うことで、より柔軟に並列実行させることを目指す
- クロージャを実現させるために、OpenJDKプロジェクトのサブプロジェクトとしてProject Lambda
UI要素の右寄せ
Web:
<div style="width:100%"> <input type="button" value="hoge" style="float:right"> </div>
Android:
<RelativeLayout android:id="@+id/RelativeLayout1" android:layout_width="fill_parent" android:layout_height="wrap_content"> <Button android:id="@+id/btn1" android:text="@string/hoge" android:layout_alignParentRight="true" android:layout_height="wrap_content" android:layout_width="wrap_content" android:textSize="15dp" ></Button> </RelativeLayout>
UI要素に枠線を付けたい
Web:
<div style="border:solid 1px black;"> 〜 </div>
Android:
非常にめんどうくさい。
【Android開発】スタイルにborderがないけど枠線を表示したい
http://se-suganuma.blogspot.com/2010/...
- background属性に指定できるような枠線用のレイアウトを別途作る
補足
随時追記する。
※関連記事:
今から1時間で,Androidアプリの開発環境を構築し,Windows上でサンプルを動作させる手順
http://language-and-engineering.hatenablog.jp/entry/20110724/p1