• Save
Android アプリケーション開発応用
Upcoming SlideShare
Loading in...5
×
 

Android アプリケーション開発応用

on

  • 1,098 views

OESF公認 ...

OESF公認
Androidアプリケーション開発応用
公式トレーニングテキスト(日本語)

Contributed by:
【作成】株式会社トップゲート
【改訂】株式会社リーディング・エッジ社
    株式会社カサレアル

【ご注意】
本テキストは、Creative Commons License BY-NC-SA 4.0のもとで提供されます。OESF会員またはコンソーシアムメンバーでない場合、本編の改変の有無にかかわらず、いかなる形態でも商用目的での利用は禁止されています。

Statistics

Views

Total Views
1,098
Views on SlideShare
904
Embed Views
194

Actions

Likes
2
Downloads
0
Comments
0

3 Embeds 194

http://oesf-edu.com 185
http://s.deeeki.com 8
https://twitter.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Android アプリケーション開発応用 Android アプリケーション開発応用 Presentation Transcript

    • Androidアプリケーション開発 応用トレーニング This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-1
    • トレーニングの目的 • Androidのアプリケーション開発における実践的 な知識、技術を身につける – Androidのコンポーネント – 実践的開発 • 演習を通して、アプリケーション開発の実践力 を養う – 開発力に主眼 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-2
    • トレーニングスケジュール • 1日目 1章 はじめに 2章 Androidコンポーネント 3章 実践的開発 • 2日目 4章 実践的開発2 5章 外部連帯 6章 実践的デバッグ ※ 一部参考資料とし、講義では取り上げない場合があります 。 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-3
    • 受講するに当たって必要なスキル • OESF公認Androidアプリケーション開発入門コー スを 受講済または、下記に示すスキルを有す ること – Androidアプリケーションの基礎的なスキルを前提と する – 複数画面からなる簡単なアプリケーションの作成が できる – JavaSEの文法に関しては一通り理解し、実経験を有し ている – Eclipseの基本的な操作を理解している This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-4
    • 1. はじめに This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-5
    • 1章の概要 • 開発環境 • 演習で用いるアプリケーション • 演習概要 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-6
    • 1.1. 開発環境 • 本トレーニングでは下記の開発ツールを用いる • インストールはすでに終了している • SDK付属のToolsにパスが通っている ソフトウェア バージョン Eclipse Eclipse IDE with built-in ADT Java SDK JDK 6 Update 23 Android SDK platform 2.3.3 Android Plug-in Android Development Tools (ADT) Ver.21 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-7
    • 1.1. 開発環境 – Eclipseワークスペース • C:android_training_appliedworkspace を指定のこと – エミュレータ • 演習で使用するエミュレータの作成方法は別ドキュメント参 照 • 6章実践的デバッグではエミュレータの設定に依存するため 、必ず指定した方法で作成すること – SDKパス • C:android_training_appliedadt-bundle-windows-x86-[日付]sdk となっている – 解答ドキュメント • 実習解答の一部は別ドキュメントとして提供しています。 • 場所: C:android_training_appliedanswer_docs_appliedhtml This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-8
    • 1.2.演習で用いるアプリケーション • 初日の演習では、OESF公認Androidアプリケーシ ョン開発入門コース で作成したRSSリーダーに 拡張を加える • 2日目の演習では、各単元ごと、それぞれの挙動 を確認できるアプリケーションを作成する ※一部の実習には時間に余裕のある人向け用に補足実習 を用意しています This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-9
    • 1.2.演習で用いるアプリケーション • RSSリーダーの画面と機能概要 – 3画面で構成されている ・・・ 画面遷移の方向 RSSリーダー 起動 ① メニュー 画面 ② 一覧画 面 ③ 詳細画 面 # 画面名 機能概要 1 メニュー画面 • 一覧画面を起動する • オプションメニューを表示する • オプションメニューがクリックされた時に、インターネットからRSSフィー ドを取得してデータベースに登録する • RSSフィード取得後、完了メッセージをダイアログで表示する 2 一覧画面 • データベースに登録されているRSSフィードを一覧形式で表示する 3 詳細画面 • 一覧画面で選択されたRSSフィードのタイトル、配信日時、配信元名、詳細 内容を表示する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-10
    • 1.3.演習概要 サービスでの 取得処理 ブロードキャストレ シーバでの処理開始 コンテントプロバイ ダでのアクセス インターネットから RSSフィードを取得す る メニュー 画面 データベースに RSSフィードを登 録 データベース データベースから RSSフィードを検索 データベースへ登 録が完了した後、 ダイアログを表示 する 取得終了のノーティ フィケーションでの 表示 インター ネット 一覧画面 一覧表示ボタンをク リックする 複数解像度 This material is licensed under the Creative Commons License BY-NC-SA 4.0. 一覧データ を 選択する 詳細画面 多言語対応 Ⅰ-11
    • 1.3.演習概要 • テーブルレイアウト – RSS_FEED テーブル 列名 型 備考 _id INTEGER GUID TEXT • RSSフィードに割り当てられる識別子 TITLE TEXT • タイトル PUBLISH_DATE TEXT • 配信日時 DESCRIPTION TEXT • 詳細内容 LINK TEXT • リンク SENDER_NAME TEXT • 配信元の名前 • プライマリキー • オートインクリメント This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-12
    • 2. Androidコンポーネント This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-13
    • 2章の概要 • • • • • アクティビティ インテント サービス ブロードキャストレシーバ コンテントプロバイダ – ※ アクティビティとインテントは確認のみとなりま すそれ以外は講義の後に、実習を行います This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-14
    • 2.1.アクティビティ • アクティビティとは? – Androidアプリケーションの画面は、アクティビティ の上にボタン、チェックボックス等の部品を配置し 、画面を作成する – 1画面は1つのアクティビティで構成する – アクティビティは実行中、一時停止といった状態を 持っている This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-15
    • 2.1.アクティビティ • サンプルコード package jp.oesf.mtgeduwg.training.rssreader; import android.app.Activity; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; public class RssReaderActivity extends Activity implements OnClickListener { public void onClick(View view) { Log.v("RssReaderActivity","Clicked"); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); View listButton = findViewById(R.id.list_button); listButton.setOnClickListener(this); } } •Activityクラスをスーパークラスとしている •必要に応じてコールバックメソッドを実装している This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-16
    • 2.1.アクティビティ • AndroidManifest.xml のサンプルコード <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="jp.oesf.mtgeduwg.training.rssreader" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"> ・・・ <activity android:label="@string/app_name" android:name="RssListActivity"></activity> </application> <uses-sdk android:minSdkVersion=“7" /> <uses-permission android:name="android.permission.INTERNET"></uses-permission> </manifest> •タグ名がactivityのタグを作成する •android:name=“アクティビティ名”の属性を指定する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-17
    • 2.1.アクティビティ • [参考]通知されるイベントを含むライフサイクル Activity起動 onCreate() ・ "戻る"で元画面に復帰 onStart() フ ア ォ グラ ウンド プ ロセス破棄 onRestart() onResume() 実行中 ・ 他Activityの割込み ・ 端末スリ ープ ・ 長時間無操作状態が続いた onPause() ・ 他アプリ ケーショ ンから メ を モリ 要求さ れる 一時停止 ・ Activityがフ アグラ ォ ウンド ビジブル ・ 他Activityの割込み ・ 長時間無操作状態が続いた に表示( 戻るボタ ン等) onStop() ・ 他アプリ ケーショ ンから メ を モリ 要求さ れる 終了 ・ Activityがフ アグラ ォ ウンド に表示( 戻るボタ ン等) バッ ク グラ ウンド 状態遷移方向 onDestroy() 状態 This material is Activity破棄 under the Creative licensed Commons License BY-NC-SA 4.0. Activityのイ ベント Ⅰ-18
    • 2.1.アクティビティ – [参考] AndroidManifest.xml の設定はリソースエディタ でも可能 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-19
    • 2.2.インテント • インテントとは? – コンポーネント間で、処理の依頼や、メッセージを やりとりする為の仕組み • インテントを利用できるコンポーネントは、アクティビティ 、ブロードキャストレシーバ、サービス – インテントを利用する具体例 • アクティビティAからアクティビティBを起動する(画面遷移 ) • アドレス帳アプリケーションから電話をかけるアプリケーシ ョンへ電話発信を依頼する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-20
    • 2.2.インテント • インテントにより、コンポーネントを呼び出す には、インテントに、呼び出し先のコンポーネ ントの情報を含めて、Androidに呼び出しを依頼 する イ ンテント オブジェ クト を作成し 送信メ て、 ソッ を実行する ド "B"が起動する – コンポーネントAからコンポーネントBを呼び出す例 インテント • "B"を呼び出す イ ンテント イ ンテント Android This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-21
    • 2.2.インテント • サンプルコード package jp.oesf.mtgeduwg.training.rssreader; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; public class RssReaderActivity extends Activity implements OnClickListener { ・・・・・・・・ public void onClick(View view) { if (R.id.list_button == view.getId()) { Intent intent = new Intent(this, RssListActivity.class); startActivity(intent); } } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-22
    • 2.3.サービス • サービスとは? – UIを持たないバックグラウンドで処理を行うコンポー ネント – サービスは画面とは独立して実行される。このため 、アクティビティが非表示になっても処理を続ける 音楽を再生(サービス未使用) 音楽を再生(サービス使用) ことができる 割込み 割込み メ ール受信により メ ール受信により 中断 中断 アクティ ビティ アクティ ビティ サービス開始 再生開始 サービス 音楽再生 中断に関係なく 処理を 完了 再生開始 アクティビティから直接音楽再生した場合と、サービ ス経由で音楽再生した場合で、メール受信によるアク ティビティの割込みが発生した時の動作の違い 音楽再生 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-23
    • 2.3.サービス • サービスを実装する方法 – サービスを新規作成する – 作成したサービスをAndroidManifest.xmlに登録する – 作成したサービスをstartServiceメソッドにて起動する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-24
    • 2.3.サービス • サービスを実装する方法 – サービスのクラスを新規作成する • 基底クラスとなるServiceクラスを継承したクラスを作成する • onBindメソッドは抽象メソッドのため実装する必要がある。 – ここではバインドを用いないためnullを返すようにしておく。 import android.app.Service; • サンプルコード import android.content.Intent; import android.os.IBinder; public class SampleService extends Service { @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. ・・・1 Ⅰ-25
    • 2.3.サービス – 必要に応じてコールバックメソ ッドを実装する • onCreate, onStartCommand,onDestroy の3つのメソッドがある • ライフサイクルを意識し、適切に実 装をする • onStartCommandは起動される度に 呼び出される • 他の2つのイベントはオブジェクト の生成と破棄の際に1回だけ呼び出 イベント名 される 内容 Service起動 onCreate() onStartCommand() 実行中 ・停止命令 onDestroy() onCreate onStartCommand サービスが起動される前に発生する イベント onDestroy サービスが破棄される前に発生する イベント This material is licensed under the Creative Commons License BY-NC-SA 4.0. 状態遷移方向 最初の起動時に発生するイベント 状態 Activityのイベン ト Service破棄 Ⅰ-26
    • 2.3.サービス • onStartCommandメソッドの戻り値として以下の 4つの定数が用意されている 説明 • 戻り値 これらの戻り値のうちどれを選ぶかによって、 サービスを起動するペンディングインテントが存在しない限りサービスは再 START_NOT_STICKY 起動 サービス強制終了時の振る舞いを制御すること されない。強制終了によりサービスが終了した場合、勝手な再起動を防ぐ場 合 が可能となっている。 に使用する START_STICKY システムはサービスを新たにインスタンス化し、サービスの再起動を行う。 サービスを起動するペンディングインテントが存在しない場合、システムは Intent をnullにしてonStartCommandを呼び出す。 startServiceによりサービスを複数回起動していたとしても再起動は1度しか 行わ れない。 START_REDELIVER_INTENT システムはサービスを新たにインスタンス化し、サービスの再起動を行う。 再起動時のonStartCommandには強制終了前と同じ内容のIntentが渡される。 再起動手順が強制終了前の起動手順と同じ。(A=>Bで起動した場合、A=>Bで 再起動) startServiceによりサービスを複数回起動していた場合は、起動した 回数分onStartCommandが呼ばれる PendingIntent・・・タイミングを指定して発行することができるIntent。システムで管理されて システムに再起動される保証がない。START_STICKYとの互換性のために START_STICKY_COMPATIBILITY This material is licensed under the Creative いる。 Ⅰ-27 用意 Commons License BY-NC-SA 4.0. されている。このモードが指定された場合、onStartCommandの引数Intentに
    • 2.3.サービス • サンプルコード @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId){ Toast.makeText(this, "Service Start", Toast.LENGTH_SHORT).show(); new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 5; i++) { Log.v(getClass().getSimpleName(), "i:" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); return START_STICKY; } @Override public void onDestroy() { Toast.makeText(this, "Service end", Toast.LENGTH_SHORT).show(); This material is licensed under the Creative } Commons License BY-NC-SA 4.0. Ⅰ-28
    • 2.3.サービス – 作成したサービスをAndroidManifest.xmlに登録する • 作成手順 i. ii. AndroidManifest.xmlを開き、Applicationタブを選択する Application Nodesの「Add」ボタンをクリックする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-29
    • 2.3.サービス iii. 表示された画面からServiceを選択し「OK」ボタンをクリッ クする ※すでに登録されているノードにカーソルがあたっている場合は 、階層を確認されるので、ラジオボタンの上を選択する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-30
    • 2.3.サービス iv. 追加されたServiceが選択されていることを確認した上で、 Nameの欄に作成したサービスのクラスの名前を入力する Browseボタンをク リックし、ブラウズ するのが便利 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-31
    • 2.3.サービス – AndroidManifest.xmlには以下のように追加される • これによりサービスのクラスとして登録されたことになる ・・・ <application ・・・> ・・・ <service android:name=“SampleService"></service> ・・・ </application> ・・・ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-32
    • 2.3.サービス – 作成したサービスをstartServiceメソッドにて起動する • Intentの引数に、呼出元のオブジェクト、呼出先のサービス のクラス情報を与えて生成する • Context#startServiceを実行する。メソッドの引数には1.で作 成したIntentオブジェクトを与える • Intent intent = new Intent(this, SampleService.class); サンプルコード (アクティビティのコードより抜粋) ・・・ⅰ startService(intent); This material is licensed under the Creative Commons License BY-NC-SA 4.0. ・・・ⅱ Ⅰ-33
    • 実 習 2.3.サービス • 実習 1 • 実習のテーマ – メニュー画面にて「menu」ボタン => 「RSS取得」メ ニューを押したときに、RSSの取得メソッドがサービ スで起動する処理を作成する 画面はそのまま 操作可能 This material is licensed under the Creative Commons License BY-NC-SA 4.0. サービスとして起動 画面への影響はなし Ⅰ-34
    • 実 習 2.3.サービス – 実習の手順 1. サービスとなるRegisterServiceクラスを新規作成する 2. RegisterServiceのonStartCommandメソッドで、RSSを取得す る 3. RegisterService#onStartCommandに開始と終了のログを出力 する – タグ:「 RegisterService 」 – メッセージ:開始時「onStartCommand start」 及び終了時 「 onStartCommand end」 4. RegistarService#onStartCommandの戻り値に「START_STICKY」 を指定する 5. RssReaderActivityのonOptionsItemSelectedメソッドにある既 存のRSS取得のロジックを削除し、 RegisterServiceをIntentを 用いて呼び出す 6. RssReaderActivity#onOptionsItemSelectedに開始と終了のログ This material is licensed under the Creative Ⅰ-35 を出力する Commons License BY-NC-SA 4.0.
    • 実 習 2.3.サービス – 設定情報 1 • 以下のクラス、メソッドを実装する 対象 サービス クラス メソッド • 新規作成する • パッケージは jp.oesf.mtgeduwg.training.rssreader とする RegisterService onStartCommand メニュー画面 概要 RssReaderActivity onOptionsItemSelected • RSS取得する • 開始と終了のログの出力する • 既存のRSS取得ロジックの削除する • RegisterServiceを起動する • 開始と終了のログの出力する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-36
    • 実 習 2.3.サービス – 設定情報 2 • 以下のファイルを編集する ファイル名 AndroidManifest.xml 概要 • RegisterServiceをサービスとして登録する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-37
    • 実 習 2.3.サービス • 確認方法 – 「RSS取得」メニューを押したときに、下記のログ出 力されていることをLogCatで確認する • RegisterService#onStartCommand – 開始ログ – 終了ログ 「onStartCommand start 」 「onStartCommand end」 • RssReaderActivity#onOptionsItemSelected – 開始ログ – 終了ログ 「onOptionsItemSelected start 」 「 onOptionsItemSelected end」 – RssReaderActivity#onOptionsItemSelectedのクローズロ グがRegisterService#onStartCommandのクローズログよ り先に出力されていることを確認する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-38
    • 実 習 2.3.サービス • 実習 1 • 実習の答え – 別ドキュメント参照 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-39
    • 実 習 2.3.サービス • 実習 1[補足] • 実習のテーマ – サービスの処理が終了したことをトーストを用いて トーストは次頁以降に説明あり 知らせる 画面はそのまま 操作可能 サービスロジック This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-40
    • 実 習 2.3. サービス • トーストとは? – 短時間だけメッセージを画面に表示する機能 – メッセージを表示する機能のみでカーソルを合わせ て操作することはできない – サービスなどUIのないコンポーネントで利用すると便 利 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-41
    • 実 習 2.3. サービス • トーストの実装 – 以下の2つのメソッドのうちどちらかを利用する • public static Toast makeText (Context context, CharSequence text, int duration) • public static Toast makeText (Context context, int resId, int duration – context: コンテキスト – text or resId: » 表示させるテキスト or 表示させるテキストのリソースID – duration: » Toast.LENGTH_SHORT (短時間) » Toast.LENGTH_LONG(長時間) – 上記2メソッドの戻り値に対してToast#showメソッド Toast.makeText(this, “TEST", Toast.LENGTH_SHORT).show(); を実行すると表示される Toast.makeText(this, R.string.test, Toast.LENGTH_LONG).show(); This material is licensed under the Creative Ⅰ-42 サンプルコード Commons License BY-NC-SA 4.0.
    • 実 習 2.3. サービス • 実習 1[補足] – サービスのロジックが終了したところで、好きなメ ッセージをトーストで表示してみる – durationを変えて表示時間が変わるか確認する – 第二引数が違うmakeTextメソッドをいずれも利用して みる This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-43
    • 実 習 2.3.サービス • 実習 1 [補足] • 実習の答え – 別ドキュメント参照 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-44
    • 2.4.ブロードキャストレシーバ • ブロードキャストレシーバとは? – ブロードキャストされたインテントに応答する為の 仕組みがブロードキャストレシーバである – ブロードキャストレシーバクラスを継承して独自の ブロードキャストレシーバを作ることができる This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-45
    • 2.4.ブロードキャストレシーバ • ブロードキャストレシーバの使用例 – Android端末起動時にメールをチェックする • ブロードキャストレシーバでAndroid端末起動完了時のブロ ードキャストインテントを受信する – どのブロードキャストインテントを受信するかは AndroidManifest.xmlにIntentFilterとして設定を記載する • ブロードキャストレシーバからメールチェックサービスを呼 び出す – ブロードキャストレシーバから直接メールチェック処理を実行 ② メールチェック メールチェッ する事も可能だが、時間のかかる処理の場合はサービスを使用 クサービス サービス実行 する方が効率が良い ① 起動完了メッセージ インテン ト ブロードキャス ト レシーバ インテン ト ブロードキャストインテント送 信 This material is licensed under the Creative インテント送信 Ⅰ-46 Commons License BY-NC-SA 4.0.
    • 2.4.ブロードキャストレシーバ • ブロードキャストレシーバを実装する方法 – ブロードキャストレシーバのクラスを新規作成する – 作成したブロードキャストレシーバを AndroidManifest.xmlに登録する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-47
    • 2.4.ブロードキャストレシーバ • ブロードキャストレシーバを実装する方法 – ブロードキャストレシーバのクラスを新規作成する • 基底クラスとなるBroadcastReceiverクラスを継承したクラス を作成する • onReceiveメソッドは抽象メソッドのため実装する必要がある • onReceiveメソッドには実際に行いたい処理を実装する import android.content.BroadcastReceiver; • サンプルコード import android.content.Context; import android.content.Intent; ・・・1 public class SampleServiceStarter extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Intent serviceIntent = new Intent(context, SampleService.class); context.startService(serviceIntent); } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-48
    • 2.4.ブロードキャストレシーバ – ※ 受け取るインテントによって処理を分岐したい場 合は Intent#getActionによりアクションを確認することによ り どのインテントを受け取っているのかを確認し、分 import android.content.BroadcastReceiver; 岐処理を記載する import android.content.Context; import android.content.Intent; public class SampleServiceStarter extends BroadcastReceiver { • サンプルコード @Override ・・・※ public void onReceive(Context context, Intent intent) { if(Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())){ Intent serviceIntent = new Intent(context, SampleService.class); context.startService(serviceIntent); } } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-49
    • 2.4.ブロードキャストレシーバ – 作成したブロードキャストレシーバを AndroidManifest.xmlに登録する • 作成手順 i. AndroidManifest.xmlを開き、Applicationタブを選択する ii. Application Nodesの「Add」ボタンをクリックする iii. 表示された画面からReceiverを選択し「OK」ボタンをクリッ クする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-50
    • 2.4.ブロードキャストレシーバ iv. 追加されたReceiverが選択されていることを確認した上で、 Nameの欄に作成したブロードキャストレシーバの名前を入力 する Browseボタンをク リックし、ブラウズ するのが便利 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-51
    • 2.4.ブロードキャストレシーバ v. 追加されたReceiverが選択されていることを確認した上で、 「Add」ボタンをクリックする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-52
    • 2.4.ブロードキャストレシーバ vi. 表示された画面から下のラジオボタンが選択されているのを 確認した上で、Intent Filterを選択し「OK」ボタンをクリック する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-53
    • 2.4.ブロードキャストレシーバ vii. 追加されたIntentFilterが選択されていることを確認した上で 、「Add」ボタンをクリックする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-54
    • 2.4.ブロードキャストレシーバ viii. 表示された画面から下のラジオボタンが選択されているのを 確認した上で、Actionを選択し「OK」ボタンをクリックする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-55
    • 2.4.ブロードキャストレシーバ ix. 追加されたReceiverが選択されていることを確認した上で、 Nameの欄に作成したアクションの名前を入力する プルダウンより選択可能 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-56
    • 2.4.ブロードキャストレシーバ ※ AndroidManifest.xmlには以下のように追加される • 下記の例ではandroid.intent.action.BOOT_COMPLETEDのブロー ドキャストインテントを捕捉し、サービスのクラスである SampleServiceStartを起動する • サンプルコード ・・・ <application ・・・> ・・・ <receiver android:name=“SampleServiceStarter"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"></action> </intent-filter> </receiver> ・・・ </application> ・・・ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-57
    • 実 習 2.4.ブロードキャストレシーバ • 実習 2 • 実習のテーマ – システム起動完了時に、RSSの取得メソッドがサービ スで起動する処理を作成する システム起動完了 This material is licensed under the Creative Commons License BY-NC-SA 4.0. サービスとして起動 画面への影響はなし Ⅰ-58
    • 実 習 2.4.ブロードキャストレシーバ • 実習の手順 1. ブロードキャストレシーバとなる RegisterServiceStarterクラスを新規作成する 2. RegisterServiceStarterのonReceiveメソッドで、 RegisterServiceを呼び出す 3. RegisterServiceStarterの設定をAndroidManifest.xmlに 追加する • RegisterServiceStarterをブロードキャストレシーバとして登録 する • RegisterServiceStarterのIntent Filterの設定として、Actionに android.intent.action.BOOT_COMPLETED(起動完了)を設定す る This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-59
    • 実 習 2.4.ブロードキャストレシーバ – 設定情報 • 以下のクラス、メソッドを実装する 対象 ブロード キャスト レシー バー クラス メソッド 概要 • 新規作成する • パッケージは jp.oesf.mtgeduwg.training.rssreader とする RegisterServiceStarter onReceive • RegisterServiceを起動する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-60
    • 実 習 2.4.ブロードキャストレシーバ – 設定情報 2 • 以下のファイルを編集する ファイル名 概要 AndroidManifest.xml • RegisterServiceStarterをレシーバとして登録する • Intent Filterの設定として、Actionに android.intent.action.BOOT_COMPLETED(起動完了)を設定す る ※API Lv 14以上の端末で動作確認する場合は以下の値を設定する 必要があります(エミュレータの場合は不要) <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-61
    • 実 習 2.4.ブロードキャストレシーバ • 確認方法 – 一度アプリケーションを起動した後に、エミュレー タを一度落とし、再度立ち上げる その際に以下の ログが出力されているのを確認する • RegisterService#onStartCommand – 開始ログ – 終了ログ 「onStartCommand start 」 「onStartCommand end」 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-62
    • 実 習 2.4.ブロードキャストレシーバ • 実習 2 • 実習の答え – 別ドキュメント参照 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-63
    • 実 習 2.4.ブロードキャストレシーバ • 実習 2[補足] – SendBroadcastプロジェクトのコードを確認し、この アプリケーションはボタンを押すと、あるアクショ ンのブロードキャストを投げるものであることを確 認する – そのアクションに対してRegisterServiceStarterが起動 するようにRssReaderプロジェクトのファイルを修正 する • アクションに対応する処理 – Toastを表示させるようにする • 確認 – RssReader起動後、SendBroadcastを起動させボタンを 押すと、RegisterServiceStarterでToastを表示されるの This material is licensed under the Creative Ⅰ-64 Commons License BY-NC-SA 4.0. を確認する
    • 実 習 2.4.ブロードキャストレシーバ • 実習 2 [補足] • 実習の答え – 別ドキュメント参照 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-65
    • 2.5.コンテントプロバイダ • コンテントプロバイダとは? – アプリケーションが保持しているデータ※を他アプ リケーションからアクセス(検索、追加、更新、削 除)できるようにする仕組み – 具体的な例 • アプリケーションから通話ログを参照する • アプリケーションからブラウザのブックマークにWebサイト を追加する • アプリケーションから連絡帳を参照する • アプリケーションからカレンダーを参照する • データとはアプリケーションが、ファイル、データベースに 永続化している情報を示す This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-66
    • 2.5.コンテントプロバイダ • コンテントプロバイダは、安全なアクセスを実 現する為に、インターフェースを取り決めてい る – 主なインターフェース # イベント名 内容 1 検索(query) データを検索し、 検索結果を返す インターフェー スが決まってい る コンテント プロバイダ query 2 追加(insert) データを追加す る insert 3 更新 (update) データを更新す る update 4 削除 (delete) データを削除す る 外部アプリ ケーション delete ■詳細はAndroid Developersの開発ガイドを参照 http://developer.android.com/intl/ja/reference/android/content/ContentProvider.html This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-67
    • 2.5.コンテントプロバイダ • コンテントプロバイダを実装する方法 – コンテントプロバイダのクラスを新規作成する – 必要に応じてコンテントプロバイダの抽象メソッド を実装する – 作成したコンテントプロバイダをAndroidManifest.xml に登録する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-68
    • 2.5.コンテントプロバイダ • コンテントプロバイダを実装する方法 – コンテントプロバイダのクラスを新規作成する • 基底クラスとなるContentProviderクラスを継承したクラスを 作成する • 以下の6つのメソッドがContentProviderクラスの抽象メソッ ドとして定義されているため、仮に全メソッドを実装してお メソッド 戻り値の型 概要 く。 • コンテントプロバイダの起動時に、実行される • プロバイダの初期化処理が正しく終了した場合は trueを返す onCreate boolean getType String • 取り扱うMIMEタイプの文字列を返す query cursor • 検索をする • 結果をCursorオブジェクトとして返す Insert int • 挿入をする • 挿入件数を返す update int • 更新する • 更新件数を返す delete • 削除する int This material is licensed under the Creative • 削除件数を返す Commons License BY-NC-SA 4.0. Ⅰ-69
    • 2.5.コンテントプロバイダ ・サンプルコード import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; public class SampleProvider extends ContentProvider { @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public String getType(Uri uri) { return null; } @Override public Uri insert(Uri uri, ContentValues values) { return null; } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-70
    • 2.5.コンテントプロバイダ ・サンプルコード (続き) @Override public boolean onCreate() { return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-71
    • 2.5.コンテントプロバイダ – 必要に応じてコンテントプロバイダの抽象メソッド を実装する • onCreateでは通常SQLiteOpenHelperのオブジェクトを生成し 、インスタンス変数として保持する コンストラクタの引数に指定するContextはgetContextメソッ ドを用いる • データベースを操作する4メソッドでは、 SQLiteOpenHelper のオブジェクトからSQLiteDatabaseのオブジェクトを取得す る 取得したSQLiteDatabaseのオブジェクトを利用して、データ ベースに対して操作を行う ※ SQLiteDatabaseオブジェクトの取得は、onCreateで行う実 装者もいる • getTypeはMIMEタイプを返すメソッドであり、指定されたURI によって種別を分けたい場合に、利用者にその種別を知らせ This material is licensed under the Creative る手段として実装する Ⅰ-72 Commons License BY-NC-SA 4.0. 複雑でない場合は通常未使用(return null;)で良い
    • 2.5.コンテントプロバイダ • サンプルコード ・・・ private SampleSqliteOpenHelper sqliteOpenHelper; private SQLiteDatabase db; @Override public boolean onCreate() { sqliteOpenHelper = new SampleSqliteOpenHelper(getContext()); return true; } ・・・ⅰ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { db = sqliteOpenHelper.getReadableDatabase(); return db.query("RSS_FEED", projection, selection, selectionArgs, null, null, sortOrder); } ・・・ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-73 ・・・ⅱ
    • 2.5.コンテントプロバイダ – 作成したコンテントプロバイダをAndroidManifest.xml に登録する • 作成手順 i. ii. AndroidManifest.xmlを開き、Applicationタブを選択する Application Nodesの「Add」ボタンをクリックする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-74
    • 2.5.コンテントプロバイダ iii. 表示された画面からProviderを選択し「OK」ボタンをクリッ クす ※ すでに登録されているノードにカーソルがあたっている 場合は、階層を確認されるので、ラジオボタンの上を選択す る This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-75
    • 2.5.コンテントプロバイダ iv. 追加されたProviderが選択されていることを確認した上で、 Nameの欄に作成したコンテントプロバイダのクラスの名前を 入力する Browseボタンをク リックし、ブラウズ するのが便利 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-76
    • 2.5.コンテントプロバイダ v. Attribute for Providerを下にスクロールし、Authoritiesタグに一 意となるコンテントプロバイダ名を指定する 通常はパッケージ名と同じにすることが多い This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-77
    • 2.5.コンテントプロバイダ – ※ AndroidManifest.xmlには以下のように追加される • これによりコンテントプロバイダのクラスとして登録された ことになる • サンプルコード ・・・ <application ・・・> ・・・ <provider android:authorities="jp.oesf.sample.sampleprovider“ android:name=“SampleProvider"> </provider> ・・・ </application> ・・・ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-78
    • 2.5.コンテントプロバイダ – 作成したコンテントプロバイダをContentResolverオブ ジェクトを用いて利用する 1. コンテントプロバイダにアクセスするためのURIをUriオブジ ェクトのparseメソッドに渡して、Uriオブジェクトを生成す る 指定するURIは content://コンテントプロバイダの Authorities の値 となる 2. Context#getContentResolverメソッドを用いてContentResolver オブジェクトを取得する ContentResolverにはContentProviderと同じ書式でquery, Uri Insert, update, delete, getTypeメソッドが用意されている・・・1 uri = Uri.parse("content:// jp.oesf.sample.sampleprovider”); ・・・2 Cursor cursor = getContentResolver().query(uri, null, null, null, null); • サンプルコード This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-79
    • 実 習 2.5.コンテントプロバイダ • 実習 3 • 実習のテーマ – RssReaderアプリにコンテントプロバイダを作成し、 外部アプリケーションからRSS_FEEDテーブルの情報 を検索できるようにする ボタン クリック This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-80
    • 実 習 2.5.コンテントプロバイダ • 実習の手順 1. コンテントプロバイダとなるRssProviderクラスを新 規作成する 2. RssProvider のonCreateメソッドで、 SQLiteOpenHelperオブジェクトを取得する 3. RssProviderのqueryメソッドで、 SQLiteDatabaseオブ ジェクトをSQLiteOpenHelper#getReadableDatabaseメ ソッドで取得する 4. RssProviderのqueryメソッドで、 SQLiteDatabase#queryを呼び出し、Cursorを戻す。 5. RssProviderの設定をAndroidManifest.xmlに追加する 6. TestContentProviderプロジェクトのMain# This material is licensed under the Creative onClickGetListメソッドを確認する (すでに実装さ Ⅰ-81 Commons License BY-NC-SA 4.0.
    • 実 習 2.5.コンテントプロバイダ – 設定情報 1 • 以下のクラス、メソッドを実装する 対象 コンテン トプロバ イダ クラス メソッド 概要 • 新規作成する • パッケージは jp.oesf.mtgeduwg.training.rssreader とする RssProvider onCreate • SQLiteOpenHelperオブジェクトを取 得する query • RSS_FEEDテーブルから、引数の条件 をそのままに検索を実行し、その結 果を返す This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-82
    • 実 習 2.5.コンテントプロバイダ – 設定情報 2 • 以下のファイルを編集する ファイル名 AndroidManifest.xml 概要 • RssProviderをコンテントプロバイダとして登録する • android:authoritiesにはjp.oesf.mtgeduwg.training.rssreaderと設 定する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-83
    • 実 習 2.5.コンテントプロバイダ • 確認方法 – TestContentProviderアプリを立ち上げ、「GET LIST」ボ タンを押すと、コンテントプロバイダ経由でデータ ベースより値を取得し、画面に一覧を表示するよう にする ボタン クリック This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-84
    • 実 習 2.5.コンテントプロバイダ • 実習 3 • 実習の答え – 別ドキュメント参照 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-85
    • 実 習 2.5.コンテントプロバイダ • 実習 3[補足] – URIを使って処理を分岐させる • RssProviderではqueryメソッド内で固定でRSS_FEEDテーブルに アクセスしているが、アプリケーションによってはアクセス するテーブルを振り分ける必要がある。 • ContentProviderでは通常query,insert,update,deleteなどのメソ ッドに与えられている引数Uriを使って処理を分岐させるこ とが可能 / テーブル名 content://xxx.xxx.xx – URIに参照するためのテーブル名相当の文字列を連結する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-86
    • 2.5.コンテントプロバイダ • UriMatcherクラスを使って処理を分岐させる – 連結された文字を判定する処理ではUriMatcherクラス を使用するとよい – UriMatcherに用意されているaddURIメソッドとmatch メソッドを使用し連結された文字列を判定する • addURI サンプルコード – uriに連結された文字列と一致したときの数値を設定 import android.content.UriMatcher; • match private static final UriMatcher uriMatcher; – 引数で指定したuriにaddURIで設定した文字列と一致しているか static{ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 確認 uriMatcher.addURI("jp.oesf.mtgeduwg.training.rssreader", "TABLE_1", 1); uriMatcher.addURI("jp.oesf.mtgeduwg.training.rssreader", "TABLE_2", 2); uriMatcher.addURI("jp.oesf.mtgeduwg.training.rssreader", “TABLE_1/#", 3); } // queryなどのメソッドの中では以下のように判定する #には数字が入る switch(uriMatcher.match(uri)){ 特定のカラムのみ検索 case 1: ・・・ jp.oesf.mtgeduwg.training.rssreader/TABLE_1 する場合などにIDを指 case 2: ・・・ jp.oesf.mtgeduwg.training.rssreader/TABLE_2 This material is licensed under the Creative case 3: ・・・ jp.oesf.mtgeduwg.training.rssreader/TABLE_1/5 定する Ⅰ-87 Commons License BY-NC-SA 4.0. default: ・・・
    • 実 習 2.5.コンテントプロバイダ • 実習 3[補足] • 実習のテーマ – URIを使って処理を分岐させる • テーブルをコード内の固定せず、URIで指定するようにする – RssProviderにUriMatcherを使った分岐処理を追加する – TestContentProviderで作成したURIにRSS_FEEDを連結させる » content://jp.oesf.mtgeduwg.training.rssreader/RSS_FEED This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-88
    • 実 習 2.5.コンテントプロバイダ • 実習 3 [補足] • 実習の答え – 別ドキュメント参照 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-89
    • 3. 実践的開発 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-90
    • 3章の概要 • • • • ノーティフィケーション 複数解像度対応 多言語対応 adbツール This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-91
    • 3.1.ノーティフィケーション • ノーティフィケーションとは? – 画面上端のステータスバーに一定時間情報を表示する機能 – ステータスバーを開いた際には、ノーティフィケーションの一 覧画面が表示され、そちらからアクティビティを起動すること ができる This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-92
    • 3.1.ノーティフィケーション • ノーティフィケーションを実装する方法 1. 2. 3. 4. 5. ノーティフィケーションを扱うためのNotificationManagerクラ スを取得する Notificationオブジェクトを生成する ノーティフィケーションの一覧からクリックされた際に起動す るペンディングインテントを生成する Notificationオブジェクトにイベント情報を設定する ノーティフィケーションを表示する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-93
    • 3.1.ノーティフィケーション • ノーティフィケーションを実装する方法 1. ノーティフィケーションを扱うためのNotificationManagerクラ スを取得する – NotificationManagerはContext#getSystemServiceにて取得可能 – 上記メソッドの引数にはContext.NOTIFICATION_SERVICE の定数を 指定する – 戻り値はObject型なのでNotificationManager型にキャストする サンプルコード import android.app.NotificationManager; import android.content.Context; ・・・ NotificationManager nm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-94 ・・・1
    • 3.1.ノーティフィケーション 2. Notificationオブジェクトを生成する • コンストラクタを呼び出しオブジェクトを生成する • コンストラクタの引数には アイコンのリソースID,ステータ スバーに表示するメッセージ、一覧に表示される時間 (ミリ サンプルコード 秒)を指定する import android.app.Notification; ・・・ Notification notification = new Notification(R.drawable.icon,"RSS取得できました", System.currentTimeMillis()); This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-95 ・・・2
    • 3.1.ノーティフィケーション 3. ノーティフィケーションの一覧からクリックされた 際に起動するペンディングインテントを生成する • PendingIntentのgetActivityメソッド(staticメソッド)により PendingIntentを生成する • getActivityの引数は4つあり、コンテキスト、リクエストコー ド(現在未使用のため、通常0)、インテント、フラグ(使 用しないなら0) を指定する サンプルコード import android.app.PendingIntent; import android.content.Intent; ・・・ PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,RssListActivity.class), 0); ・・・3 フラグはPendingIntent.FLAG_UPDATE_CURRENTなど 詳細は http://developer.android.com/reference/android/app/PendingIntent.html This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-96
    • 3.1.ノーティフィケーション 4. Notificationオブジェクトにイベント情報を設定する • Notification#setLatestEventInfoによりイベント情報を設定する • setLatestEventInfoの引数は4つあり、コンテキスト、タイト ル、テキスト、ペンディングインテント を指定する サンプルコード notification.setLatestEventInfo(this, "RssReader", "RSS取得完了", pendingIntent); This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-97 ・・・4
    • 3.1.ノーティフィケーション 5. ノーティフィケーションを表示する • NotificationManager#notifyにより、実際にノーティフィケー ションを表示をする • notifyの引数は2つあり、id(アプリ内でそのノーティフィケ ーションを一意にする数字), Notificationオブジェクト を指 定する サンプルコード nm.notify(0,notification); This material is licensed under the Creative Commons License BY-NC-SA 4.0. ・・・5 Ⅰ-98
    • 3.1.ノーティフィケーション 1-5までのサンプルコードを一つにまとめると以下のようになる import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; ・・・ NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); Notification notification = new Notification(R.drawable.icon,"RSS取得できました", System.currentTimeMillis()); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,RssListActivity.class), 0); notification.setLatestEventInfo(this, "RssReader", "RSS取得完了", pendingIntent); nm.notify(0,notification); ・・・ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-99
    • 実 習 3.1.ノーティフィケーション 実習 4 • 実習のテーマ – サービスでRSS取得ロジックが終了した際に、ノーテ ィフィケーションを用いて終了した旨を知らせる処 理を作成する – ノーティフィケーションの一覧画面にて該当のノー ティフィケーションをクリックすると、一覧画面 ロジック終 (RssListActivity)に遷移する クリック 了 サービスとして起動 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-100
    • 実 習 3.1.ノーティフィケーション 実習 4 • 実習の手順 1. RegisterService#onStartCommandのRSS取得ロジックの 後に以下を実装する i. NotificationManager を取得する ii. Notificationオブジェクトを生成する iii. 一覧画面(RssListActivity)に遷移するようなPendingIntentを 生成する iv. Notificationオブジェクトにイベント情報を設定する v. ノーティフィケーションを表示する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-101
    • 実 習 3.1.ノーティフィケーション 実習 4 – 設定情報 1 • 以下のクラス、メソッドを実装する 対象 クラス メソッド RSS取得 RegisterService onStartCommand 概要 • ノーティフィケーションを表示する • PendingIntentのフラグは0とする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-102
    • 実 習 3.1.ノーティフィケーション 実習 4 – 設定情報 2 「RssReader」と表 • 以下のように表示されるようにする 示 R.drawable.icon の画像を表示 「RSS取得でき ました」と表 示 「RSS取得完 了」と表示 This material is licensed under the Creative Commons License BY-NC-SA 4.0. 表示時点での 時刻を表示 Ⅰ-103
    • 実 習 3.1.ノーティフィケーション 実習 4 • 確認方法 – 「RSS取得」メニューを押す等によりRSS取得を行った 際に、以下のようなノーティフィケーションが表示さ れる – ノーティフィケーションの一覧から、該当のノーティ フィケーションを押すとRSSリーダーの一覧画面に遷移 する クリック This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-104
    • 実 習 3.1.ノーティフィケーション 実習 4 • 実習の答え @Override public int onStartCommand(Intent intent, int flags, int startId) { super.onStartCommand(intent, flags, startId); StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitAll().build()); Log.v("RegisterService", "onStartCommand start"); new RssFeedRegister(this) .registration("http://www.oesf.jp/modules/news/index.php?page=rss"); // TODO ネットワーク接続が出来ない場合は上記の処理をコメントアウトし、下のコメントアウトを外す // new RssFeedRegister(this).registration("android.xml"); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); Notification notification = new Notification(R.drawable.icon, "RSS取得できました", System.currentTimeMillis()); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, RssListActivity.class), 0); notification.setLatestEventInfo(this, "RssReader","Rss取得完了",pendingIntent); nm.notify(0, notification); Log.v("RegisterService", "onStartCommand end"); return START_STICKY; } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-105
    • 実 習 3.1.ノーティフィケーション 実習 4[補足] • 実習のテーマ – 一覧画面に遷移した際にnotificationを削除するように する • 実習の答え – 別ドキュメント参照 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-106
    • 3.2. 複数解像度対応 • 複数解像度対応 – Androidではバージョン1.6より複数解像度に正式に対応している – どのAndroid端末にインストールされるかわからない場合は、複 数解像度対応をしなければ、正しく表示されない可能性がある – Androidがどのような仕組みで1つのアプリが複数の解像度に対 応しているのかを知っておく必要がある This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-107
    • 3.2. 複数解像度対応 • • • • Densityとスクリーンサイズ DIP (Density Independent Pixel) スケーリング 複数解像度対応Tips This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-108
    • 3.2. 複数解像度対応 • Densityとスクリーンサイズ – AndroidではDensity(密度)とスクリーンサイズにより端末をカテ ゴライズしている – DensityはDPI(Dots Per Inch/1インチ当たりのドット数)の値によ り以下のように分類している – 以下の分類により、呼び出す画像ファイルのディレクトリが分 かれることにより、そのDensityに適した画像を表示することが できる Density DPIの範囲 みなしDPI値 対応する画像ファイルディレクトリ Low-Density 100dpi-140dpi 120dpi res/drawable-ldpi Medium-Density 140dpi-180dpi 160dpi res/drawable-mdpi High-Density 190dpi-250dpi 240dpi res/drawable-hdpi Extra High-Density 250dpi以上 320dpi res/drawable-xhdpi ※ みなしDPI値 例 Low-Densityの端末は、すべてDPIが120dpiだとして扱われる This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-109
    • 3.2. 複数解像度対応 – スクリーンサイズは以下に分類されている – 以下の分類により、呼び出すレイアウトファイルの ディレクトリが分かれることにより、その画面サイ ズに適したレイアウトファイルを呼び出すことがで きる 名称 画面のサイズ 対応するレイアウトファイルディレクトリ Small screen 426dp x 320dp res/layout-small Normal screen 470dp x 320dp res/layout Large screen 640dp x 480dp res/layout-large Extra Large screen 960dp x 720dp res/layout-xlarge This material is licensed under the Creative 参考 http://developer.android.com/intl/ja/guide/topics/resources/providingⅠ-110 Commons License BY-NC-SA 4.0. resources.html#AlternativeResources
    • 3.2. 複数解像度対応 – 2つの分類をまとめると、以下の表のようになる This material is licensed under the Creative 参考 http://developer.android.com/intl/ja/guide/topics/resources/providingⅠ-111 Commons License BY-NC-SA 4.0. resources.html#AlternativeResources
    • 3.2.複数解像度対応 • DIP (Density Independent Pixel) – サイズを直接指定する際に、通常はピクセル(Pixel/px)を使うが、ピク セルだとDensityにより意図しないUIとなる – AndroidではDIP(Density Independent Pixel)という仮想的なピクセル単位 の概念を導入し、それに対応できるようにしている – DIPの単位はdipないしdpと表記するが、dpが推奨されている – pixels = dips * (density / 160) の式で計算される つまり160dpi= Medium-Densityでは1px=1dpとなる – DIPと似た概念としてScale-independent Pixels (sp)があるが、Densityだけで なくユーザーのフォントサイズ設定を加味した値となる。 – [補足]Androidで用意されているJavaの各メソッドでのサイズの値を渡す引 数はpxなのかdpなのかを意識する必要がある。 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-112
    • 3.2.複数解像度対応 • スケーリング – 画像ファイルはDensityによって呼び出すディレクトリが用意されているが 、すべてが用意されていない、res/drawableのみしか用意されていない等の 場合がありうる – 上記の場合に、Medium-DensityのScale Densityを1として、Densityによって画 像のサイズを拡大縮小して表示するスケーリング機能が用意されている – スケーリングしたくない画像はres/drawable-nodpiに配置すれば、スケーリ ングされずそのままの解像度で表示される Scale Density Density Scale Density Extra-High-Density 2.0 High-Density 1.5 Medium-Density 1 Low-Density 0.75 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-113
    • 3.2.複数解像度対応 • 複数解像度対応Tips – – – – レイアウトのwidthやheightのサイズ指定はwrap_contentやmatch_parent 数値指定が必要な場合はpxではなくdpを用いる 画像ファイルはDensityによって適切に用意する スクリーンサイズの違いを意識し、横方向には詰め込みすぎない どうしても詰め込みたい場合はSmall Screenのみレイアウトファイルを別 途用意する – Javaのコードでピクセル値をハードコードしない。dpに変換する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-114
    • 3.2.複数解像度対応 • 複数解像度対応Tips(続き) – スクリーンサイズの区分のうち対応しないスクリーンを設ける際は、 AndroidManifest.xmlのsupports-screensの設定を記載すればよい AndroidManifest.xmlのサンプル (Small Screenに対応していない) ・・・ <application> ・・・ <supports-screens android:xlargeScreens="true" android:largeScreens=“true” android:normalScreens=“true” android:smallScreens=“false” /> ・・・ </application> ・・・ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-115
    • 実 習 3.2.複数解像度対応 実習 5 • 実習のテーマ – MultiResolutionプロジェクトのアプリを、スクリーンサイズとDensityの 違うエミュレータでそれぞれ動かし、その画面とソースを確認する ldpi mdpi This material is licensed under the Creative Commons License BY-NC-SA 4.0. hdpi Ⅰ-116
    • 実 習 3.2.複数解像度対応 実習 5 • 実習の確認ポイント – Small-Screenではボタンが2段組みとなっていることを 確認 => res/layout-small/main.xmlが読み込まれている – R.drawable.droidは解像度ごとに用意された別画像が表 示されていることを確認 => res/drawable-Xdpi/droid.jpg が表示されている – R.drawable.droid_nodpi はスケーリングされずに1つの 画像が表示されていることを確認 => res/drawable-nodpi/droid_nodpi.jpgが表示されてい This material is licensed under the Creative Ⅰ-117 Commons License BY-NC-SA 4.0. る
    • 実 習 3.2.複数解像度対応 • 実習の確認ポイント(続き) – R.drawable.droid_scalingはスケーリングされて、解像 度に合わせてサイズが拡大縮小されて表示されてい ることを確認 => res/drawable/droid_scaling.jpgがスケーリングされ て表示されている – 表示されているテキストは上はpx指定、下はdp、sp指 定であるため、下のテキストは解像度に合わせてサ イズが変わっているのを確認する => res/layout/main.xmlが読み込まれている – 画像のマージンはdp指定されているため、解像度に This material is licensed under the Creative Ⅰ-118 Commons License BY-NC-SA 4.0. 合わせてサイズが変わっているのを確認する
    • 実 習 3.2.複数解像度対応 Small-Screenではボタンが 2段に分かれて表示され る R.drawable.droid Densityごとに別画 像が用意されてい る 上はpx指定 下はdp,sp指定 上は解像度によりサ イズが変わる R.drawable.droid_scaling スケーリングされて表示 される R.drawable.droid_nodpi スケーリングされず、 すべて同じ解像度で 表示される This material is licensed under the Creative Commons License BY-NC-SA 4.0. 画像のマージンはdp 指定している Ⅰ-119
    • 実 習 3.2.複数解像度対応 実習 5 • 実習の手順 1. 以下の3つのエミュレータが用意されているので、 それを起動させMultiResolutionプロジェクトのアプ リを起動し表示された画面とソースを確認する エミュレータ名 スクリーンサイズとDensity QVGA-small-ldpi Small Screen, Low-Density HVGA-normal-mdpi Normal Screen, Medium-Density WVGA-normal-hdpi Normal Screen, High-Density This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-120
    • 実 習 3.2.複数解像度対応 実習 5 • 確認方法 – 実習の確認ポイントを確認する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-121
    • 3.3. 多言語対応 • 多言語対応 – Androidのアプリケーションは世界各国で使われる可能性がある ため多言語に対応するべきである – Androidには文字列をリソースファイルとして記述しておけば、 簡単に多言語対応できる仕組みが用意されている – 端末での言語設定に合わせてres/values-[言語コード], ないし res/values-[言語コード]-r[地域コード] のディレクトリ配下のリソ ースファイルを読みにいくようになっている – 端末設定言語固有のディレクトリが存在しない場合は、 res/values配下を読み込む This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-122
    • 3.3. 多言語対応 例 • English(Australia)の場合はvalues-en-rAU • Australia以外のEnglishの場合はvaluesen • 日本語の場合はvalues-ja • 上記以外の場合はvalues が読み込まれる 言語コードの指定 ISO 639-1形式 http://www.loc.gov/standards/iso639-2/php/code_list.php 地域コードの指定 ISO 3166-1-alpha-2形式 http://www.iso.org/iso/country_codes/iso_3166_code_lists/ english_country_names_and_code_elements.htm This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-123
    • 実 習 3.3. 多言語対応 実習6 • 実習のテーマ – エミュレータの言語設定を変更すると、それに応じ て呼び出される文字列リソースファイルが変更され ることを確認する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-124
    • 実 習 3.3. 多言語対応 実習 6 • 実習の手順 1. res/values-en, res/values-en-rAU, res/values-ja を作成す る 2. res/values/strings.xml を 作成した3ディレクトリにコ ピーする 対象 キー 値 res/values/strings.xml go_to_list_page_button_label 一覧表示(デフォルト) 3. 各strings.xmlのgo_to_list_page_button_labelキーの値 res/values-en/strings.xml go_to_list_page_button_label 一覧表示(英語) を以下のように変更する res/values-en-rAU/strings.xml go_to_list_page_button_label 一覧表示(オーストラリア) res/values-ja/strings.xml go_to_list_page_button_label 一覧表示(日本) This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-125
    • 実 習 3.3. 多言語対応 実習 6 • 確認方法 – RssReaderをエミュレータで起動する 言語設定を変更するとメニュー画面のボタンの表示テ キストが変更されることを確認する 言語 表示文字列 値 日本語 go_to_list_page_button_label 一覧表示(日本) English(Australia) go_to_list_page_button_label 一覧表示(オーストラリア) English ※Australia以外 go_to_list_page_button_label 一覧表示(英語) 上記どれでもない go_to_list_page_button_label 一覧表示(デフォルト) This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-126
    • 実 習 3.3. 多言語対応 実習 6 • 言語設定方法 i. ホーム画面で「menu」ボタン => 「Settings」を押す ii. Settings画面にて「Language & keyboard」 を押す This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-127
    • 実 習 3.3. 多言語対応 iii. Language & keyboard settings画面で「Select language」 を押す iv. Locale画面にて対象の言語を押す This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-128
    • 実 習 3.3. 多言語対応 実習 6 • 実習の答え (該当部のみ) – res/values/strings.xml <string name=“go_to_list_page_button_label”>一覧表示(デフォルト)</string> – res/values-en/strings.xml <string name=“go_to_list_page_button_label”>一覧表示(英語)</string> <string name=“go_to_list_page_button_label”>一覧表示(オーストラリア)</string> – res/values-en-rAU/strings.xml <string name="go_to_list_page_button_label">一覧表示(日本)</string> – res/values-ja/strings.xml This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-129
    • 3.4.adbツール • adbツールとは? – SDKに付属しているデバイスやエミュレータの状態を管理するツ ール – コマンドプロンプトにて、コマンドを打ち利用する – <SDK_ROOT>/platform-toolsにPathを通している場合は、adbコマ ンドをどのディレクトリでも認識する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-130
    • 実 習 3.4.adbツール 実習 7 • 実習のテーマ – 説明に合わせて載っている操作を実際に行い、adbツ ールの使い方を学ぶ 1. adb -help adbツールのヘルプが表示される C:¥>adb -help Android Debug Bridge version 1.0.29 -d - directs command to the only connected USB device returns an error if more than one USB device is present. -e - directs command to the only running emulator. returns an error if more than one emulator is running. -s <serial number> - directs command to the USB device or emulator with the given serial number. Overrides ANDROID_SERIAL This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-131
    • 実 習 3.4.adbツール 実習 7 2. adb devices 実行中のエミュレータと実機の一覧を表示する C:¥>adb devices List of devices attached emulator-5554 device 3. adb uninstall <パッケージ名> C:¥>adb uninstall jp.oesf.mtgeduwg.training.testcontentprovider パッケージ名 に該当するアプリケーションをアンインストールする Success 4. adb install <apkのパス> C:¥>adb install C:¥android_training_applied¥workspace¥TestContentProvider¥bin¥Te アプリケーションをインストールする stContentProvider.apk 72 KB/s (15719 bytes in 0.210s) pkg: /data/local/tmp/TestContentProvider.apk This material is licensed under the Creative Success Commons License BY-NC-SA 4.0. Ⅰ-132
    • 実 習 3.4.adbツール 実習 7 5. adb logcat ログを出力する (終了:Ctrl + C) C:¥>adb logcat D/dalvikvm( 149): GC_EXTERNAL_ALLOC freed 135K, 50% free 2972K/5895K, external 4730K/5582K, paused 62ms W/KeyCharacterMap( 149): No keyboard for id 0 W/KeyCharacterMap( 149): Using default keymap: /system/usr/keychars/ 6. adb logcat -c C:¥>adb logcat -c ログをクリアする 7. adb shell C:¥>adb shell 端末(エミュレータ)に接続しシェルを起動する # This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-133
    • 実 習 3.4.adbツール 実習 7 (ここからシェルでの操作) 8. cd <ディレクトリパス> カレントディレクトリの移動する # cd /data/data/jp.oesf.mtgeduwg.training.rssreader cd /data/data/jp.oesf.mtgeduwg.training.rssreader 9. pwd カレントディレクトリを表示する # pwd pwd /data/data/jp.oesf.mtgeduwg.training.rssreader 10.lsls # ファイルやディレクトリの情報を表示する ls databases lib This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-134
    • 実 習 3.4.adbツール 実習7 (ここからsqlite3コマンド) 11.sqlite3 <データベースファイルのパス> カレントディレクトリの移動する 12. .help ヘルプを表示する 13..dump ダンプファイルを表示する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-135
    • 実 習 3.4.adbツール 実習 7 11..schema CREATE文を表示する 12. <SQL文>; SQL文を発行する 13..exit sqlite3コマンドを抜ける This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-136
    • 3.5.JUnit • JUnitとは – Javaプログラムのユニットテスト(単体テスト)を行うためのテ スティングフレームワーク – 作成したプログラムが、意図した挙動をするのか確認するテス トコードを作成し、それを実行することにより検証を行える – テストがプログラム化しており、何度でも機械的に実行が可能 なため品質の担保に役立つ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-137
    • 3.5.JUnit • Android用に拡張されたJUnitとは – AndroidではJUnit3を元にして、Android用にカスタマイズされ提 供されている – ユーザーの画面操作やライフサイクルのイベント(onCreate等)を 発行することが可能 => ある程度は単体テストの枠を超えて、シナリオテストにも利 用可能 – 通常JUnitのランナーは開発マシン上のJava VMで動作するが、 AndroidのJUnitランナーはエミュレータや実機にTest用アプリケ ーションをインストールし実行することのより、テストを実施 している。 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-138
    • 3.5.JUnit • JUnit 基底クラスの構造 – JUnitのテストクラスはjunit.framework.TestCaseクラス を基底クラスとして、拡張したクラスとする必要が ある – Androidでは上記TestCaseクラスを、テスト対象に合わ せて継承したクラスを用意している – 用途に合わせてその継承したクラスを利用すれば良 い This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-139
    • 3.5.JUnit – TestCaseクラスとAndroidが提供しているテスト用クラ スの関係 junit.framework.TestCase InstrumentationTestCase ActvitivtTestCase ActivityInstrumentationTestCase2 ActivityUnitTestCase SingleLaunchActivityTestCase AndroidTestCase ServiceTestCase ProviderTestCase2 ApplicationTestCase This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-140
    • 3.5.JUnit – 各基底クラスの概要 • ActivityInstrumentationTestCase2 – ボタンを押す等の画面の操作が可能 • ActivityUnitTestCase – アクティビティのライフサイクル上のイベント(onCreate等)を実行す ることが可能 • ServiceTestCase – サービスを実行することが可能 • ProviderTestCase2 – コンテントプロバイダを実行することが可能 • ApplicationTestCase – アプリケーションのテストに利用可能 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-141
    • 3.5.JUnit • JUnit実コード例 – まずはAndroidと関係なく、一般的なJUnitのコード • テスト対象のコード 引数2つを足し算をして返すメソッド public class Foo { public int add(int x, int y){ return x + y; } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-142
    • 3.5.JUnit • テストコード import junit.framework.TestCase; public class FooTest extends TestCase { ・・・1 private Foo foo = null; protected void setUp() throws Exception { super.setUp(); foo = new Foo(); } ・・・2 protected void tearDown() throws Exception { super.tearDown(); } ・・・3 public void testAdd(){ int actual = foo.add(4, 5); assertEquals(9, actual); } ・・・4 ・・・5 } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-143
    • 3.5.JUnit 1. 2. 3. 4. 5. junit.framework.TestCaseを継承し、クラスを作成する クラス名は「テスト対象のクラス名」 + “Test”とすることが通例 setUpメソッドは、テストが開始される前に実行される テストの準備(データの整備、オブジェクトの生成等)をこのメ ソッドで行う tearDownメソッドは、テストが終了した際に実行される テスト後のクリーンアップ(データを元に戻す等)をこのメソッ ドで行う テストメソッドとなる メソッド名はtestXXXとし、public void で引 数なしとする assertEqualsメソッドは、ここでテスト対象のコードが正しく振舞 っているかを確認する。第一引数に期待値、第二引数に実際のテ ストにより得た値をセットすることにより、2つが正しい場合はテ スト通過、そうでない場合はエラーとなる 他にassertTrue, assertFalse等がある This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-144
    • 3.5.JUnit • ActivityInstrumentationTestCase2の例 テスト対象 のActivity public class FooActivityTest extends ActivityInstrumentationTestCase2<FooActivity> { public FooActivityTest() { super(FooActivity.class); テスト対象クラスのクラス情 } 報 public void testUrlFieldKeyInput() { // キーの送信(“T",“E",“S",“T"と入力) sendKeys(KeyEvent.KEYCODE_T, KeyEvent.KEYCODE_E KeyEvent.KEYCODE_S, KeyEvent.KEYCODE_T); assertEquals(“test”, urlField.getText().toString()); キーの入力 } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-145
    • 3.5.JUnit • ActivityInstrumentationTestCase2の例 package jp.oesf.mtgeduwg.training.test; テスト対象 のActivity public class AddActivityTest extends ActivityInstrumentationTestCase2<AddActivity> { public AddActivityTest() { super(AddActivity.class); } public void testAddButtonClick() { UIスレッドへの処理の依頼 getActivity().runOnUiThread(new Runnable() { public void run() { urlField.setText("http://www.oesf.jp/modules/news/index.php?page=rss"); addButton.performClick(); ボタンのクリックを実行 }}); getInstrumentation().waitForIdleSync(); UIスレッドの処理終了を待 assertTrue(existsUrlAddressById(10)); つ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-146
    • 3.5.JUnit • ActivityInstrumentationTestCase2の例 (画面遷移) public void testAddButtonClick() { 遷移先Activityをモニターする ActivityMonitor monitor = new ActivityMonitor("jp.oesf.mtgeduwg.training.rssreader.RssListActivity", null, false); getInstrumentation().addMonitor(monitor); getActivity().runOnUiThread(new Runnable() { public void run() { addButton.performClick(); 遷移先Activityを取得 }}); Activity rssListActivity = getInstrumentation().waitForMonitor(monitor); if(rssListActivity != null){ rssListActivity.finish(); } } 遷移先Activityをfinish This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-147
    • 3.5.JUnit • ActivityUnitTestCaseの例 package jp.oesf.mtgeduwg.training.test; テスト対象 のActivity public class AddActivityUnitTest extends ActivityUnitTestCase<AddActivity> { public AddActivityUnitTest() { super(AddActivity.class); } @Override protected void setUp() throws Exception { super.setUp(); } public void testSendResumeEvent() throws Exception { onResumeの実行 Intent intent = new Intent(Intent.ACTION_MAIN); startActivity(intent, null, null); getInstrumentation().callActivityOnResume(getActivity()); } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-148
    • 3.5.JUnit • ServiceTestCaseの例 package jp.oesf.mtgeduwg.training.test; テスト対象 のService public class AddServiceTest extends ServiceTestCase <AddService> { public AddServiceTest() { super(AddSer viceclass); } @Override protected void setUp() throws Exception { super.setUp(); Intentを生成し、それ } を元にServiceを起動 public void testService() { Intent intent = new Intent(AddService.class.getName()); int result = startService(intent); ・・・ } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-149
    • 3.5.JUnit • メモ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-150
    • 3.5.JUnit • JUnitプロジェクトの作り方 1. Eclipseのメニュー[File]から[New]->[Other]を選択する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-151
    • 3.5.JUnit 2. Androidフォルダ内の「Android Test Project」を選択 し、「Next」ボタンを押す 3. Project Nameの欄にテストプロジェクト名を指定し て「Next」ボタンを押す This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-152
    • 3.5.JUnit 4. TestTargetのプロジェクトを選択して「Finish」ボタ ンをクリックする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-153
    • 3.5.JUnit 5. 次にTestCaseを作成する。4.で作成したテストプロジ ェクトを選択した状態で、 [File]から[New]->[Other] を選択する 6. Javaフォルダ->JUnitフォルダ内の「JUnit Test Case」 を選択し、「Next」ボタンを押す 6 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-154
    • 3.5.JUnit 7. New JUnit 3 のボタンが選ばれていることを確認し、 Nameにクラス名、Superclassに親クラスを入力、 Class under testにはTestTargetのクラス名を指定して 「Finish」ボタンを押す 7 This material is licensed under the Creative Commons License BY-NC-SA 4.0. 注意 テストクラス生成後は そのクラスのコンストラ クタが未実装でコンパイ ルエラー状態なのでコン ストラクタを追加するこ Ⅰ-155 と。
    • 3.5.JUnit • AndroidManifest.xml – Eclipseを用いてテストプロジェクトを作成すると、自動で以下 の太字2か所が追加される (テスト実行のためには必須) <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="jp.oesf.mtgeduwg.training.rssreader.test" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <uses-library android:name="android.test.runner" /> </application> <uses-sdk android:minSdkVersion="7" /> <instrumentation android:targetPackage="jp.oesf.mtgeduwg.training.rssreader" android:name="android.test.InstrumentationTestRunner" /> </manifest> This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-156
    • 3.5.JUnit – テストの実行方法 • テストプロジェクトを右クリック Run as -> Android JUnit Test を選択する エミュレータ or 実機を接続している必要がある This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-157
    • 3.5.JUnit – テストの成功/失敗の確認 • JUnitビューにて確認可能 失敗 成功 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-158
    • 実 習 3.5.JUnit 実習 8 • 実習のテーマ – JUnitのテストケースを実際に作成する – 2つのテストケースを作成する – 上記を通して、Androidでの単体テストの方法を習得 する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-159
    • 実 習 3.5.JUnit 実習 8 • 実習の手順 1. RssReaderをテスト対象とするRssReaderTestプロジェ クトを作成する 2. RssReaderActivity と RegisterService をテストするクラ スをそれぞれ作成する 3. それぞれに、一つずつテストメソッドを実装する i. ii. RssReaderActivityのテストでは 「一覧表示」ボタンを押し、一覧表示画面が表示される そ こに表示されているListViewの件数が0件より大きいことを 確認 するテストを記載する ヒント ListView#getCount()にてListViewの件数を取得可能 This material is licensed under Creative RegisterServiceのテストでは the4.0. Ⅰ-160 Commons License BY-NC-SA ResigsterServiceを実行する前後でDBのRSS_FEEDテーブルに
    • 実 習 3.5.JUnit 実習 8 • 確認方法 – テストを実行し、グリーンになる This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-161
    • 実 習 3.5.JUnit 実習 8 • 実習の答え – RssReaderActivityTest.java package jp.oesf.mtgeduwg.training.rssreader.test; import jp.oesf.mtgeduwg.training.rssreader.R; import jp.oesf.mtgeduwg.training.rssreader.RssReaderActivity; import android.app.Activity; import android.app.Instrumentation.ActivityMonitor; import android.test.ActivityInstrumentationTestCase2; import android.widget.Button; import android.widget.ListView; public class RssReaderActivityTest extends ActivityInstrumentationTestCase2<RssReaderActivity>{ public RssReaderActivityTest(){ super(RssReaderActivity.class); } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-162
    • 実 習 3.5.JUnit – RssReaderActivityTest.java (続き) public void testOnClickListButton(){ ActivityMonitor monitor = new ActivityMonitor("jp.oesf.mtgeduwg.training.rssreader.RssListActivity", null, false); getInstrumentation().addMonitor(monitor); final Button button = (Button) getActivity().findViewById(R.id.list_button); getActivity().runOnUiThread(new Runnable() { @Override public void run() { button.performClick(); } }); getInstrumentation().waitForIdleSync(); Activity rssListActivity = getInstrumentation().waitForMonitor(monitor); ListView listView = (ListView) rssListActivity.findViewById(android.R.id.list); assertTrue(listView.getCount() > 0); if(rssListActivity != null){ rssListActivity.finish(); } } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-163
    • 実 習 3.5.JUnit – RegisterServiceTest.java package jp.oesf.mtgeduwg.training.rssreader.test; import jp.oesf.mtgeduwg.training.rssreader.RegisterService; import jp.oesf.mtgeduwg.training.rssreader.helper.DatabaseOpenHelper; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.test.ServiceTestCase; public class RegisterServiceTest extends ServiceTestCase<RegisterService> { public RegisterServiceTest() { super(RegisterService.class); } public void testRegisterService() { int before; int after; Intent intent = new Intent(RegisterService.class.getName()); before = countDb(); startService(intent); after = countDb(); assertTrue(after - before > 0); } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-164
    • 実 習 3.5.JUnit – RegisterServiceTest.java (続き) private int countDb() { int result = 0; Cursor cursor = null; DatabaseOpenHelper databaseOpenHelper = new DatabaseOpenHelper(getContext()); SQLiteDatabase database = null; try { database = databaseOpenHelper.getReadableDatabase(); cursor = database.query(“RSS_FEED”, null, null, null, null, null, null); result = cursor.getCount(); } finally { if (database != null) { database.close(); JUnitではCursorを明示的 } にcloseしなければ例外と if(cursor != null){ cursor.close(); なる } } return result; } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-165
    • 実 習 3.5.JUnit • 実習 8[補足] • 実習のテーマ – 他のメソッドもテストする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-166
    • 4. 実践的開発2 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-167
    • 4章の概要 • アクティビティとタスク – タスク – アフィニティ – 起動モード • タスクの管理 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-168
    • 4.1.アクティビティとタスク • アプリケーションのタスク – Androidのタスクとはアクティビティを管理する仕組みである – タスクとは、アクティビティをスタック構造で管理している – 違うアプリケーションのアクティビティを起動した際も、その アクティビティは同一のタスクとして扱われる タスク 起動 タスク 起動 タスク 起動 ルートアクティビティ 戻る 戻る This material is licensed under the Creative Commons License BY-NC-SA 4.0. 戻る Ⅰ-169
    • 4.1.アクティビティとタスク • アフィニティ – 直訳すると 親和性 – アプリケーション内のすべてのアクティビティは、デフォルト ではすべて同一タスクになるような親和性(アフィニティ)が ある – 通常は同じアプリケーションのアクティビティは、同じアフィ ニティを持つが、個別のアクティビティにアフィニティを設定 することも可能 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-170
    • 4.1.アクティビティとタスク • アフィニティの設定と挙動 – アフィニティの値はAndroidManifest.xmlに登録可能である – アフィニティを設定してもデフォルトの振る舞いでは、各アク ティビティは同一のタスクとなる – 別タスクで起動する場合は、startActivityメソッドに渡すインテ ントにフラグの設定を記載する必要がある => taskAffinityを指定しても、フラグがなければ同一タスクとな る AndroidManifest.xml サンプルコード ・・・ <activity android:name=“TestActivity" android:taskAffinity=“jp.sample.test"></activity> ・・・ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-171
    • 4.1.アクティビティとタスク • インテントのフラグ – インテントのフラグはandroid.content.Intentに用意されている – Intent#setFlagsにフラグの値を渡せばよい – 別タスクで起動する場合は、startActivityメソッドに渡すインテ ントにフラグの設定を記載する必要がある – タスク関連のフラグは以下となる FLAG_ACTIVITY_NEW_TASK アフィニティに基づき新しいタスクを起動 FLAG_ACTIVITY_MULTIPLE_TASK 上記フラグと同時に用いて、多重に新しいタスクを起動 ・・・ Intent intent = new Intent(this, NextActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); ・・・ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-172
    • 4.1.アクティビティとタスク – FLAG_ACTIVITY_NEW_TASK C:foo X:foo A:foo タス ク:foo B B:bar タス A:xxx ク:bar タス ク:foo X Y:bar X:foo A:foo タス ク:foo B:yyy タス X:xxx B:bar タス ク:bar タス B:yyy ク:foo A:foo タス Y:yyy B:yyy ク:foo タス ク:bar Y ク:bar C 新しく起動したアクティビティは、新しいタスクに配置されるが、 すでに同じアフィニティを持っているタスクがある場合は、 そのタスクに配置される。 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-173
    • 4.1.アクティビティとタスク – FLAG_ACTIVITY_NEW_TASK C:bar A:foo タス ク:foo B B:bar タス A:xxx ク:bar タス ク:foo C C:bar B:bar タス A:xxx ク:bar タス B:bar タス A:xxx ク:bar タス ク:foo B ク:foo 但し、すでに同じアクティビティがタスクのルートアクティビティとして配置 されている場合は、新しいタスクは開始されず、そのアクティビティが存在 しているタスクがフォアグラウンドに移動する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-174
    • 4.1.アクティビティとタスク – FLAG_ACTIVITY_MULTIPLE_TASK A:foo タス ク:foo B B:bar タス A:xxx ク:bar タス ク:foo C C:bar タス ク:bar B:bar タス A:xxx ク:bar タス ク:foo B:bar タス ク:bar タス B ク:bar B:bar タス A:xxx ク:bar タス ク:foo FLAG_ACTIVITY_NEW_TASKと共に指定すると、 同じアフィニティを持つタスクがすでに存在していても、新たにタスクが開始され This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-175
    • 4.1.アクティビティとタスク • android:allowTaskReparenting属性 – AndroidManifest.xmlのapplication要素ないしactivity要素の属性 として指定することができる – application要素の場合はそのアプリケーション全体に、activity 要素の場合はそのアクティビティに効果を与える – 値を”true”とした際には、あるタスクがフォアグラウンドに移動 する際に、そのタスクと同じアフィニティを持っているアクティ ビティがすべて、そのタスクに吸収、再配置される – ルートアクティビティに対しては無効(再配置はされない) C:bar X:bar A:foo タス ク:foo X:bar B:bar タス ク:bar C: bar を起動 フォアグラウンド A:foo タス ク:foo B:bar タス ク:bar フォアグラウンド This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-176
    • 4.1.アクティビティとタスク • アクティビティと起動モード android:launchMode 属性 – AndroidManifest.xmlのactivity要素の属性として指定することがで きる 起動モード 配置され る タスク Standard (デフォル ト) 開始したタ スク 同一アク タスクに他の ティビティ アクティビ の複数生成 ティを含めら れるか 複数生成さ れる 可 singleInstance 参考 新しく処理される(新しいインスタン スが生成) 同一アクティビティがスタックの最上 位にある場合は再利用され、その他の 場合は新しく処理される singleTop singleTask 同一アクティビティのインスタン スが存在する段階での、新しいイ ンテントの処理方法 新しいタス ク(常に ルートアク ティビティ となる) 既存タスクにある場合はそのタスクが フォアグランドになり、対象アクティ ビティよりも上にスタックされたアク ティビティは破棄される(最上位に該 当アクティビティが無い場合はインテ ントはドロップ) 1つのみ生成 される 不可 新しく処理される This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-177 (自分のみ)
    • 4.1.アクティビティとタスク • メモ欄 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-178
    • 4.2.タスクの管理 • タスクのクリア – アプリケーションを操作せず一定時間経過後に、アプリケー ションをランチャーから再起動すると、ルートアクティビティ以 外が破棄される –上記振る舞いはデフォルトの振る舞いとなり、activity要素の属性 を変更することによって振る舞いを変更することができる D:bar C:foo B:bar A:foo タス ク:foo 一定時間経過後 D:bar アプリを起動 C:foo B:bar A:foo タス ク:foo This material is licensed under the Creative Commons License BY-NC-SA 4.0. 破棄 Ⅰ-179
    • 4.2.タスクの管理 –android:alwaysRetainTaskState – “true”に指定されている場合、タスクのクリアを行わない – 設定はルートアクティビティに対してのみ有効 D:bar D:bar C:foo C:foo B:bar A:foo タス ク:foo アプリを起動 B:bar A:foo タス ク:foo This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-180
    • 4.2.タスクの管理 –android:clearTaskOnLaunch – “true”に指定されている場合、一定時間が経過していなくと も常にタスクの状態がクリアされ、ルートアクティビティ 以外は破棄される – 正確にはバックグラウンドに移った時点で破棄されている – 設定はルートアクティビティに対してのみ有効 D:bar C:foo B:bar A:foo タス ク:foo 常に D:bar アプリを起動 C:foo B:bar A:foo タス ク:foo This material is licensed under the Creative Commons License BY-NC-SA 4.0. 破棄 Ⅰ-181
    • 4.2.タスクの管理 • タスクとインテントフラグ – FLAG_ACTIVITY_CLEAR_TOP – アクティビティを起動すると、すでに同じアクティビティ が配置されいる場合、それより上にあるアクティビティを破 棄する –起動モードが”standard”の場合は、表示するアクティビティ も破棄し、新しいインスタンスを生成する C B C Aを起動 B A A タスク タスク 起動モードが”standard”以外の 場合は、Aは破棄されない This material is licensed under the Creative Commons License BY-NC-SA 4.0. A 破棄 Ⅰ-182
    • 4.2.タスクの管理 – FLAG_ACTIVITY_REORDER_TO_FRONT – アクティビティを起動すると、すでに同じアクティビティ が配置されいる場合、それをタスクの先頭に移動させる –起動モードが”standard”の場合は、表示するアクティビティ も破棄し、新しいインスタンスを生成する C B A Aを起動 C A B タスク タスク This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-183
    • 4.2.タスクの管理 – FLAG_ACTIVITY_NO_HISTORY – このフラグを設定して起動したアクティビティは、バック グラウンドに移動すると、アクティビティが終了する –activityのandroid:noHistory属性を”true”にしても、同様の振る 舞いをする B Cを起動 C A A タスク タスク This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-184
    • 4.2.タスクの管理 – FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS – このフラグを設定して起動したアクティビティは、「最近 使用したタスクの一覧」に表示されなくなる –activityのandroid:excludeFromRecents属性を”true”にしても、 同様の振る舞いをする –ルートアクティビティに対してのみ有効 ※ 「最近使用したタスクの一覧」はホームキーの長押しか 履歴ボタンを押すと表示される ハードボタンが搭載されている端末 Honeycomb以降のハードボタンが搭載されていない端末など ホームボタン長押し This material is licensed under the Creative Commons License BY-NC-SA 4.0. 履歴ボタン Ⅰ-185
    • 実 習 4.3. 実習 実習 9 • 実習のテーマ – FLAG_ACTIVITY_NEW_TASK の挙動を確認する – すべての遷移に上記フラグをセットし、以下のよう になることを確認する C:foo X:foo A:foo タス ク:foo B B:bar タス A:xxx ク:bar タス ク:foo X Y:bar X:foo A:foo タス ク:foo B:yyy タス X:xxx B:bar タス ク:bar タス B:yyy ク:foo A:foo タス Y:yyy B:yyy ク:foo タス ク:bar Y ク:bar This material is licensed under the Creative Commons License BY-NC-SA 4.0. C Ⅰ-186
    • 実 習 4.3. 実習 実習 9 • 実習の手順 1. Affinityプロジェクトの以下の点を修正し完成させる スタブプロジェクトのファイル構成を確認する 各アクティビティ(C.java除く)にonClickGoTo?Buttonを実装す る 画面遷移の際は、すべてインテントのフラグ FLAG_ACTIVITY_NEW_TASK をセットするようにする iii. アクティビティA,X,Cが同一のアフィニティになるよう AndroidManifest.xmlを編集する iv. 同様にアクティビティB,Yも同一のアフィニティになるよう にする i. ii. This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-187
    • 実 習 4.3. 実習 実習 9 – 設定情報 1 • 以下のクラス、メソッドを実装する 対象 クラス メソッド - 各アクティビ ティ onClickGoTo?Button 概要 • 画面遷移参照 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-188
    • 実 習 4.3. 実習 実習 9 – 設定情報 2 • 以下のファイルを編集する ファイル名 概要 AndroidManifest.xml • 各アクティビティにandroid:taskAffnityを設定する • 手順の通りグループ分けができていれば、値は適宜決めるこ と This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-189
    • 実 習 4.3. 実習 実習 9 • 確認方法 – 画面のボタンを押していくと、A=>B=>X=>Y=>Cと遷移す ることを確認する – Cまで遷移した後に、戻るボタンを押していくと、 C=>X=>A=>Y=>Bと遷移することを確認する [補足]ホームボタン長押しでもタスクが2つできている C:foo ことが分かる X:foo A:foo タス ク:foo B B:bar タス A:xxx ク:bar タス ク:foo X Y:bar X:foo A:foo タス ク:foo B:yyy タス X:xxx B:bar タス ク:bar タス B:yyy ク:foo A:foo タス Y:yyy B:yyy ク:foo タス ク:bar Y ク:bar This material is licensed under the Creative Commons License BY-NC-SA 4.0. C Ⅰ-190
    • 実 習 4.3. 実習 実習 9 • 実習の答え – A.java (他のアクティビティの解答は省略) ・・・ public void onClickGoToBButton(View v){ Intent intent = new Intent(this, B.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } ・・・ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-191
    • 実 習 4.3. 実習 実習 9 • 実習の答え – AndroidManifest.xml ・・・ <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".A" android:label="@string/app_name"> ・・・・ <activity android:name="B" android:taskAffinity="jp.oest.mtgeduwg.training.affinity.b"></activity> <activity android:name="X"></activity> <activity android:name="Y" android:taskAffinity="jp.oest.mtgeduwg.training.affinity.b"></activity> <activity android:name="C"></activity> ・・・ ※ アフィニティの値は一例なので、何でも良い This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-192
    • 実 習 4.3. 実習 実習 9[補足1] • 実習のテーマ – 最後の遷移先である画面Cから画面Bに、他と同様に FLAG_ACTIVITY_NEW_TASKフラグを設定し遷移するよ うにする – そうすると画面Cから画面Bへは遷移せず、画面Yが表 示される – 画面Bがルートアクティビティであるため、画面Bの 属するタスクがフォアグラウンドに移動するだけと なる This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-193
    • 実 習 4.3. 実習 実習 9[補足2] • 実習のテーマ – Affinityプロジェクトを自由に改変し、その他のフラグ 、属性の設定による挙動の変化を確認する – 実業務で利用頻度が比較的高いと思われる FLAG_ACTIVITY_XXXXXから確認するのがお勧め This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-194
    • 5. 外部連帯 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-195
    • 5章の概要 • 外部連帯概要と方法 • JSONの解析 • [補足実習] This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-196
    • 5.1.外部連帯概要と方法 • Androidの特徴は外部連帯可能であること • ネットワークに常時接続できることを前提とし、Cloudサービ ス(サーバーサイド)と連動したアプリケーションを作成す ることができる • Cloudサービスと端末間でのデータのやり取りは、XMLやJSON が用いられることが多い • 端末側でXML、JSONを解釈できるようにする必要がある • なお、昨今ではJSONでの実装をする例が多い This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-197
    • 5.1.外部連帯概要と方法 • サービスの一例 • 有名なサービスはXML、JSONいずれでも提供していることが多い This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-198
    • 5.1.外部連帯概要と方法 • XMLとは • Extensible Markup Language • データの開始と終了をタグで囲んで、意味づけを行うフォーマット • タグは入れ子にできるので階層構造を表現することはできるが、循 環構造はそのままでは表現できないため、属性で指定することにな る 広く使われており文字コードも指定することが可能 タグ及びその中に属性があるため、冗長で可読性が悪いのが欠点 • • <?xml version="1.0" encoding="UTF-8"?> <statuses type="array"> <status> <created_at>Thu Oct 21 19:13:18 +000 <id>28052969836</id> <user> <id>20536157</id> <name>A Googler</name> This material is licensed under the Creative ・・・・ Commons License BY-NC-SA 4.0. Ⅰ-199
    • 5.1.外部連帯概要と方法 • JSONとは • JavaScript Object Notation • 元々はJavaScriptでのオブジェクトの記述方法であったが、そ のままデータフォーマットの仕様とした • • • 非常にシンプルで分かりやすい 文字コードは基本的にUTF-8のみ 機能が限定的(「数値」「文字列」「真偽値(true、false)」「配列 」「オブジェクト」「null」)であり表せるデータが限られることと 、循環したデータは扱えないが欠点 [ { "created_at": "Thu Oct 21 19:13:18 +0000 2010", "id": 28052969836, "user": { "id": 20536157, “name”: “Alicensed under the Creative Googler”,・・・ This material is Commons License BY-NC-SA 4.0. Ⅰ-200 参考 http://www.json.org/json-ja.html/
    • 5.1.外部連帯概要と方法 • AndroidにおけるHTTP通信 • • JavaのHTTP通信と同様の方法で良い java.netのクラスを利用する 実装例解説 1. アクセス先のURLを元にURLオブジェクトを生成する 2. HttpURLConnection オブジェクトを取得する またHTTPのメソッドもセットする 3. 実際に接続し、リソースをInputStreamとして取得する その後、InputStreamをbyte[] として保持する 4. byte[]をByteArrayOutputStreamに書き出す 5. HTTP通信の後始末を行う This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-201
    • 5.1.外部連帯概要と方法 import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.URL; ・・・ private void getHttp() { HttpURLConnection http = null; InputStream in = null; ByteArrayOutputStream out = null; byte[] byteArray = null; Int size = 0; try { URL url = new URL(“http://www.oesf.jp”); http = (HttpURLConnection) url.openConnection(); http.setRequestMethod("GET"); http.connect(); in = http.getInputStream(); byteArray = new byte[in.available()]; This material is licensed under the Creative Commons License BY-NC-SA 4.0. ・・・1 ・・・2 ・・・3 Ⅰ-202
    • 5.1.外部連帯概要と方法 out = new ByteArrayOutputStream(); while ((size = in.read(byteArray)) != -1) { out.write(byteArray, 0, size); } } catch (Exception e) { Log.e(TAG, e.getMessage(), e); } finally { try { in.close(); } catch (Exception e) { Log.e(TAG, e.getMessage(), e); } try { http.disconnect(); } catch (Exception e) { Log.e(TAG, e.getMessage(), e); } } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. ・・・4 ・・・5 Ⅰ-203
    • 5.2.JSONの解析 • JSONの解析 – HTTP通信で取得したデータはJSON形式の文字列であ る – その文字列をオブジェクトとして扱い、データを利 用できるようにする必要がある – それにはorg.json パッケージの JSONObject と JSONArray クラスを利用する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-204
    • 5.2.JSONの解析 • JSONObject – JSONのオブジェクトを扱うクラス – JSONのオブジェクトは”,“ “-” で囲われている – コンストラクタの第一引数にStringのJSONを渡すと JSONObjectを生成できる – JSONObjectの持つ値はJSONObject#getXXXX(Steing key) で取得可能 (※ XXXXは下記表参照) 値を取得するためのメソッド getDouble get getInt getBoolean getLong getJSONArray getString getJSONObjects This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-205
    • 5.2.JSONの解析 • JSONArray – JSONの配列を扱うクラス – JSONのオブジェクトは”*“ “+” で囲われている – コンストラクタの第一引数にStringのJSONを渡すと JSONArrayを生成できる – JSONArrayの持つ値の取得メソッドはJSONObjectと同 一名称のメソッドが用意されている(前頁参照) This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-206
    • 5.2.JSONの解析 • JSONの解析例 – 以下のJSONの解析を行う [ { “foo”:”abc”, “bar”:”xyz” }, { “foo”:”123”, “bar”:”789” } ] This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-207
    • 5.2.JSONの解析 実装例解説 1. StringのJSONからJSONArrayオブジェクトを生成する 2. JSONArrayの配列の数だけfor文をループさせ、配列内 の解析を行う 3. 今回解析するJSONはJSONの配列内はオブジェクトと なっているため、JSONArrayよりi番目のJSONObjectを 取得する 4. 3で取得したJSONObjectよりキーを引数として、必要 な値を取得し処理する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-208
    • 5.2.JSONの解析 サンプルコード import org.json.JSONArray; import org.json.JSONObject; ・・・ try { JSONArray entries = new JSONArray(jsonStr); StringBuilder builder = new StringBuilder(); for (int i = 0; i < entries.length(); i++) { JSONObject post = entries.getJSONObject(i); ・・・1 解析するJSON ・・・2 [ ・・・3 { builder.append(“foo:” + post.getString(“foo”) + “n”); ・・・4 builder.append(“bar:" + post.getString(“bar") + "n"); builder.append("n"); “foo”:”abc”, “bar”:”xyz” }, { } } catch (Exception e) { Log.e(TAG, e.getMessage(), e); } ・・・ This material is licensed under the Creative Commons License BY-NC-SA 4.0. “foo”:”123”, “bar”:”789” } ] Ⅰ-209
    • 5.2.JSONの解析 builder.toString()した結果 foo:abc bar:xyz foo:123 bar:789 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-210
    • 実 習 5.2.JSONの解析 実習 10 • 実習のテーマ – イベント開催支援ツールATND(アテンド)よりJSON 値を取得し、その値を解析する – ATNDでは • http://api.atnd.org/events/?format=json&count=20&keyword=an droid にアクセスすることによってandroidというワードを含んだイ ベント情報を取得することができる – 解析結果を画面に表示する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-211
    • 実 習 5.2.JSONの解析 実習 10 • 実習の手順 1. Httpプロジェクトの以下の点を修正し完成させる i. res/layout/main.xmlにある「GET & Parse JSON」ボタンの onClick属性の値を確認し、それを元にボタンが押された際 のメソッドをアクティビティであるMain.javaに記載する ii. 上記で作成したメソッドにHTTP通信を行いJSONを取得する 実装を行う iii. 取得したJSONを解析し、画面に表示する 表示先は res/layout/main.xmlにTextViewが1つ用意されているので、そ のTextViewにセットする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-212
    • 実 習 5.2.JSONの解析 実習 10 – 設定情報 1 • 以下のクラス、メソッドを実装する 対象 クラス メソッド 概要 ボタンロジッ ク Main.java 各自確認 • JSON取得と解析 • 解析結果の表示(表示先は各自Main.xmlの TextViewのIDを確認のこと) – 取得先URL • http://api.atnd.org/events/?format=json&count=20&keyword=andr oid – Main.javaにて定数定義済み ※ 外部とネットワークが繋がっていない環境では、講師の指示に従うこと – 表示方法 This material is licensed under the Creative Ⅰ-213 • 解析結果の表示方法はどのような形でも良いが、解答例では Commons License BY-NC-SA 4.0.
    • 実 習 5.2.JSONの解析 実習 10 – 解析するJSONは以下のようなフォーマットとなってい る。 { キー “event_url”はイベントのURL、“title”はイベントタイトルと なる。 "results_returned":20, "results_available":2316, この2つの値を画面に表示するようにすること "events":[ { ・・・ "event_url":"http://atnd.org/events/xxxxx", "title":”XXXXXX”, ・・・ ※解析対象 }, { ・・・ "event_url":"http://atnd.org/events/xxxxx", "title":”XXXXXX”, ・・・ }, ], ・・・ } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-214
    • 実 習 5.2.JSONの解析 実習 10 • 確認方法 – “GET & Parse JSON”ボタンをクリックすると、解析した 結果が表示される This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-215
    • 実 習 5.2.JSONの解析 実習 10 • 実習の答え • 別ドキュメント参照 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-216
    • 実 習 5.3.JSONの解析 実習 10[補足] • 実習のテーマ • 取得したJSONより他のデータも表示できるようにしまし ょう • 例) – イベント開催日時 – 開催場所 – 定員 ※どのようなキーが存在するかは各自で確かめる • 解答 – この補足実習には解答ドキュメントはありません This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-217
    • 6. 実践的デバッグ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-218
    • 6.1 実践的デバッグ • より高度なEclipseのデバッグ – エクセプションブレークポイント • プロファイリング – ヒーププロファイリング – メソッドプロファイリング This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-219
    • 6.1. 実践的デバッグ • 概要・手順 – 簡単な画像表示のアプリケーションを作成 – 初期状態では問題を含む – デバッグ・プロファイリングの技術を駆使して問題 を解決していく This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-220
    • 6.1. 実践的デバッグ • トレーニングの手順 – 本トレーニングでは既に作成済の「ProfilingTest」プ ロジェクトを使用する – ProfilingTestでは各チェックポイントに合わせて「 ProfilingTestActivityX.java」ファイルが用意されている 変更する <application android:icon="@drawable/icon" ので講師の指示にしたがって、Manifestファイルを書 android:label="@string/app_name" > <activity android:name=".ProfilingTestActivity6" き換えて実行する > android:label="@string/app_name" <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".PhotoViewActivity" ></activity> </application> This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-221
    • 6.1. 実践的デバッグ • プロジェクトの作成 – ProfilingTestプロジェクトの作成 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-222
    • 6.1. 実践的デバッグ • プロジェクトの詳細設定 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-223
    • 6.1. 実践的デバッグ • res/rawにphotos*.zipをコピー – このzipの中には画像が複数入っている • コンパイルをするとRクラスが書き換わる。 – R.raw.photos*でアクセス可能 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-224
    • 6.1. 実践的デバッグ CheckPoint 1 • まずはzipを読み込んでbitmapのリストを作る – ProfilingTestActivity.java • 参照ファイル:ProfilingTestActivity1.java public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { //とりあえずZipをBitMapのリストで取得する List<Bitmap> photos = getPhotos(); } catch (IOException e) { e.printStackTrace(); } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-225
    • 6.1. 実践的デバッグ • ZIPの読み込み – ProfilingTestActivity.java private List<Bitmap> getPhotos() throws IOException{ ZipInputStream zipInputStream = null; List<Bitmap> results = new ArrayList<Bitmap>(); try { zipInputStream = new ZipInputStream(getResources().openRawResource(R.raw.photos)); while(true){ ZipEntry nextEntry = zipInputStream.getNextEntry(); if(nextEntry == null){ break; } if(nextEntry.isDirectory()){ continue; } Bitmap bitmap = BitmapFactory.decodeStream(zipInputStream); results.add(bitmap); } }finally{ if(zipInputStream!=null){ zipInputStream.close(); } } return results; } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-226
    • 6.1. 実践的デバッグ • Run>Run As>Android Application – エラー発生! This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-227
    • 6.1. 実践的デバッグ • DDMSパースペクティブ>LogCatを確認 – (OOME)OutOfMemoryError発生! This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-228
    • 6.1. 実践的デバッグ • 確認すると・・・ – スタックトレースを見るとBitmapを作成しているとこ ろでエラー発生 – 現在getPhotos()メソッドではList<Bitmap>で返してい るが、メモリがないので厳しい模様 – データベースに保存することにする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-229
    • 6.1. 実践的デバッグ CheckPoint 2 • 今回はデータベースへの保存はあらかじめ作ってある PhotoDBHelperクラスを利用する – jp.oesf.mtgeduwg.training.profilingtestにPhotoDBHelperクラスをコ ピーする • PhotoDBHelper#insertBitMap(name,bytes)を利用する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-230
    • 6.1. 実践的デバッグ • ProfilingTestActivityにメソッド追加 – 参照ファイル:ProfilingTestActivity2.java private void preparePhotos() throws IOException{ PhotoDBHelper photoDBHelper = new PhotoDBHelper(this); ZipInputStream zipInputStream = null; try { zipInputStream = new ZipInputStream(getResources().openRawResource(R.raw.photos)); while(true){ ZipEntry nextEntry = zipInputStream.getNextEntry(); if(nextEntry == null){ break; } if(nextEntry.isDirectory()){ continue; } photoDBHelper.insertBitMap(nextEntry.getName(), toBytes(zipInputStream),nextEntry.getTime()); } }finally{ if(zipInputStream!=null){ zipInputStream.close(); } } } public static byte[] toBytes(InputStream input) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] buffer = new byte[4096]; int n = 0; while (-1 != (n = input.read(buffer))) { output.write(buffer, 0, n); } This material is licensed under the Creative return output.toByteArray(); Commons License BY-NC-SA 4.0. } Ⅰ-231
    • 6.1. 実践的デバッグ • ProfilingTestActivity#onCreate変更 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { preparePhotos(); }catch (IOException e) { e.printStackTrace(); } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-232
    • 6.1. 実践的デバッグ • Run>Run As>Android Application – 画像読み込みとDB保存成功 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-233
    • 6.1. 実践的デバッグ CheckPoint 3 • 画像表示用のViewを追加 – ImageView • 写真情報のリストを取得 – DBHelper#getPhotoInfos() • Idを指定してBitmapを取得 – DBHelper#getPhotoBitMap(id) • カーソルキーでリストの画像を次々に表示する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-234
    • 6.1. 実践的デバッグ • ProfilingTestActivityにフィールド追加 – 参照ファイル:ProfilingTestActivity3.java LinearLayout linearLayout; TextView textView; ImageView imageView; List<PhotoInfo> photoInfos ; int currentPhotoIndex; This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-235
    • 6.1. 実践的デバッグ • PhotoDBHelper内にPhotoInfoクラスが存在してい る – 画像を抜かして情報のみを持つクラス public static class PhotoInfo { public final long id; public final String title; public final long updatetime; public PhotoInfo(long id, String title , long updatetime) { super(); this.id = id; this.title = title; this.updatetime = updatetime; } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-236
    • 6.1. 実践的デバッグ • ProfilingTestActivity#onCreateを変更 /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { preparePhotos(); } catch (IOException e) { throw new RuntimeException(e); } getPhotoList(); linearLayout = new LinearLayout(this); linearLayout.setOrientation(LinearLayout.VERTICAL); textView = new TextView(this); imageView = new ImageView(this); linearLayout.addView(textView); linearLayout.addView(imageView); setContentView(linearLayout); } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-237
    • 6.1. 実践的デバッグ • ProfilingTestActivityにメソッド追加 private void getPhotoList() { PhotoDBHelper photoDBHelper = new PhotoDBHelper(this); photoInfos = photoDBHelper.getPhotoInfos(); } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-238
    • 6.1. 実践的デバッグ • ProfilingTestActivityにメソッド追加 @Override protected void onResume() { super.onResume(); setImage(); } public void setImage(){ PhotoDBHelper photoDBHelper = new PhotoDBHelper(this); PhotoInfo photoInfo = photoInfos.get(currentPhotoIndex); textView.setText(currentPhotoIndex + ":" + photoInfo.title); Bitmap bitmap = photoDBHelper.getPhotoBitmap(photoInfo.id); imageView.setImageBitmap(bitmap); } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-239
    • 6.1. 実践的デバッグ • ProfilingTestActivityにメソッド追加 – キー入力でListのindexをインクリメント、デクリメン トする @Override public boolean onKeyDown(int keyCode, KeyEvent event) { int lastIndex = photoInfos.size()-1; if (KeyEvent.KEYCODE_DPAD_LEFT == keyCode || KeyEvent.KEYCODE_DPAD_DOWN == keyCode) { currentPhotoIndex = currentPhotoIndex == lastIndex ? 0 : currentPhotoIndex+1; setImage(); } else if (KeyEvent.KEYCODE_DPAD_RIGHT == keyCode || KeyEvent.KEYCODE_DPAD_UP == keyCode) { currentPhotoIndex = currentPhotoIndex == 0 ? lastIndex : currentPhotoIndex-1; setImage(); } return true; } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-240
    • 6.1. 実践的デバッグ • Run>Run As>Android Application – 一枚目の画像が表示された This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-241
    • 6.1. 実践的デバッグ • 左キーを押す – エラー発生(LogCatで確認するとOOME) This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-242
    • 6.2.エクセプションブレークポイント • エクセプションブレークポイント – 任意のエクセプションが発生した時にブレーク • 条件ブレークポイント – ブレークポイントを設定したのだけど、止めたいと ころはループの終わりの辺り… – あるフラグが立っている時だけ、止めたい… This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-243
    • 6.2.エクセプションブレークポイント • 方法 – OOMEでのエクセプションブレークポイントを張る – その時のメモリヒープの内容を見る This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-244
    • 6.2.エクセプションブレークポイント • Run->Add Java Exception BreakPoint This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-245
    • 6.2.エクセプションブレークポイント • キャメルケースマッチングでOOMEと入力 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-246
    • 6.2.エクセプションブレークポイント • Run>Debug As>Android Application – 下図のようにブレークする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-247
    • 6.3.ヒーププロファイリング • ヒープの確認をする – 設定の確認 • Window > Preference > Android > DDMS – HPROF Actionの設定を「Open in Eclipse」にする This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-248
    • 6.3.ヒーププロファイリング • ヒープの確認をする – 実行 • DDMSパースペクティブに移動 • Device ViewのDump HPROF Fileをクリック This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-249
    • 6.3.ヒーププロファイリング • hprofファイルの出力 – 出力先はeclipseのタイトルバーに表示される This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-250
    • 6.3.ヒーププロファイリング • jhatでの解析 – Java SDKに標準でついてくるhprof解析ツール • Java SDKにパスを通しておく事 – httpサーバーが立ち、ブラウザ経由で使用する – 使用方法 • コマンドプロンプトから • jhat hprofファイルパス This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-251
    • 6.3.ヒーププロファイリング • http://localhost:7000/ – Show Heap histogramをクリック This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-252
    • 6.3.ヒーププロファイリング • ヒープのヒストグラムを見る – クラス毎にメモリ使用量の多い順に表示される。イ ンスタンス数も表示される • インスタンス数はリークの検出に有効! – 各クラスをクリックするとそのクラスのインスタン ス一覧が表示される This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-253
    • 6.3.Show class and instance • 使用しているクラスから、そのインスタンスの内容を見る – 今回はProfilingTestActivityを見てみる – class jp.oesf.mtgeduwg.training.profilingtest.ProfilingTestActivity をクリック This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-254
    • 6.3.Show instance • Refereces to this object: にインスタンス一覧が表示される – 今回はインスタンスが一つあるだけなのでそれをク リック This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-255
    • 6.3.インスタンス詳細-メンバー • Instance data members:にインスタンスのメンバ ーが表示される – それぞれクリックする事でインスタンスの詳細が分 かる This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-256
    • 6.3.ヒーププロファイリング • References to this object: にこのインスタンスを参 照している他のインスタンスが分かる – 意図しないオブジェクトから参照されてないか? – 意図しない参照のせいでGC時に解放されずリークす る事がある This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-257
    • 6.3.ヒーププロファイリング • 今回はOOMEなので、余計なメモリを消費して いないかを調べていく • Instance data membersを順々に見ていく This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-258
    • 6.3.ヒーププロファイリング • ImageView > BitmapDrawableの内容を見てみる • mBitMapがフィールドとして存在している – 仮説:今回のbitmapは2枚同時存在できないほど大き いものなのでBitmapを読み込む時点で表示済みbitmap があればメモリが足りなくなるのでは? This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-259
    • 6.3.ヒーププロファイリング CheckPoint 4 • Bitmap読み込み時にはImageViewにあるBitmapを リリースするようにする • その状態で実行してみて次のページにいければ OK This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-260
    • 6.3.ヒーププロファイリング • ProfilingTestActivityにフィールド追加 – 参照ファイル:ProfilingTestActivity4.java Bitmap currentBitmap; This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-261
    • 6.3.ヒーププロファイリング • ProfilingTestActivity#setImage修正 public void setImage(){ PhotoDBHelper photoDBHelper = new PhotoDBHelper(this); PhotoInfo photoInfo = photoInfos.get(currentPhotoIndex); textView.setText(currentPhotoIndex + ":" + photoInfo.title); if(currentBitmap !=null){ currentBitmap.recycle(); currentBitmap = null; } currentBitmap = photoDBHelper.getPhotoBitmap(photoInfo.id); imageView.setImageBitmap(currentBitmap); } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-262
    • 6.3.ヒーププロファイリング • Run>Run As>Android Application – 二枚目以降の画像が表示された This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-263
    • 6.3.ヒーププロファイリング • 横長画像なので端末を横にしてみたい。 – エミュレーター上でCTRL+F12を押すと端末が回転す る – OOMEが発生 – 先ほどと同じようにHPROFをダンプして調べてみる This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-264
    • 6.3.ヒーププロファイリング • ProfilingTestActivityのクラスを見る – インスタンスが2つ存在している This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-265
    • 6.3.ヒーププロファイリング • ProfilingTestActivityのインスタンス内容を見る – フィールドの内容は残ったまま This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-266
    • 6.3.ヒーププロファイリング CheckPoint 5 • なぜProfilingTestActivityのインスタンスが2つあ るか? – ⇒回転時にActivityを破棄してからもう一度Activityを createするが、その時に古いActivityが残っているので はないか? – 内部で使用しているviewがProfilingTestActivityの参照を 持っているので消えないのでは? • ProfilingTestActivityのインスタンス内のフィール ドがクリアされていない – ⇒onPause()でクリアすれば良いのでは? This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-267
    • 6.3.ヒーププロファイリング • フィールドのクリア – 参照ファイル:ProfilingTestActivity5.java – profilingTestActivity#onPause()を追加 @Override protected void onPause() { super.onPause(); if(currentBitmap!=null){ currentBitmap.recycle(); } currentBitmap = null; linearLayout = null; textView= null; imageView= null; photoInfos= null ; } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-268
    • 6.3.ヒーププロファイリング • ProfilingTestActivity#onCreateの修正 – ContextをapplicationContextにする @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { preparePhotos(); } catch (IOException e) { throw new RuntimeException(e); } getPhotoList(); Context applicationContext = getApplicationContext(); linearLayout = new LinearLayout(applicationContext); linearLayout.setOrientation(LinearLayout.VERTICAL); textView = new TextView(applicationContext); imageView = new ImageView(applicationContext); linearLayout.addView(textView); linearLayout.addView(imageView); setContentView(linearLayout); } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-269
    • 6.3.ヒーププロファイリング • ProfilingTestActivityにステート保存、読込の追加 – 回転前にIDを保存しておく • onSaveInstanceState – 回転後にIDを読み込む • onRestoreInstanceState @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putInt("currentPhotoIndex", currentPhotoIndex); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); currentPhotoIndex = savedInstanceState.getInt("currentPhotoIndex"); } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-270
    • 6.3.ヒーププロファイリング • Run>Run As>Android Application – 横にしても画像が表示された This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-271
    • 6.4.メソッドプロファイリング • 一通り動作するようにはなったが、速度が遅い 。これを改善したい – メソッドプロファイリングで遅いメソッドを特定す る This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-272
    • 6.4.メソッドプロファイリング • 該当アプリケーションをデバッグモードで起動 – DDMS>devices>StartMethodProfilingをクリック This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-273
    • 6.4.メソッドプロファイリング • アプリケーションの左キーを押して次の画像を 表示する This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-274
    • 6.4.メソッドプロファイリング – DDMS>devices>StopMethodProfilingをクリック This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-275
    • 6.4.メソッドプロファイリング • TraceViewの表示 – StopMethodProfilingをクリックするとTraceViewが表示 される • ネストしたメソッド毎に色分け表示されて実行時間や占有% がわかる This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-276
    • 6.4.TraceViewの解析 • TraceViewの解析 – ここで一番時間をとっているのは紫の13番目のメソ ッド • BitmapFactory.nativeDecodeByteArray • 写真集のjpgデータが大きすぎるか? • 調べてみると1Mバイト弱。3072x2048という巨大なデータ… This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-277
    • 6.4.メソッドプロファイリング CheckPoint 6 • 単純に小さいbitmapに変更する – 参照ファイル:ProfilingTestActivity6.java – ProfilingTestActivity#preparePhotos()の変更 – R.raw.photos_sには1/4のサイズのjpegが入っている private void preparePhotos() throws IOException{ PhotoDBHelper photoDBHelper = new PhotoDBHelper(this); ZipInputStream zipInputStream = null; try { zipInputStream = new ZipInputStream(getResources().openRawResource(R.raw.photos_s)); while(true){ ZipEntry nextEntry = zipInputStream.getNextEntry(); if(nextEntry == null){break; } if(nextEntry.isDirectory()){ continue;} photoDBHelper.insertBitMap(nextEntry.getName(), toBytes(zipInputStream),nextEntry.getTime()); } }finally{ if(zipInputStream!=null){ zipInputStream.close(); } } } This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-278
    • 6.4.メソッドプロファイリング • もう一度メソッドプロファイリングを実行する – 問題ないくらいの速度になった This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-279
    • 6.5. 実践的デバッグまとめ • アプリケーションが意図しない動作をした場合 の高度なデバッグ方法 – エクセプションブレークポイント • メモリリークの検出方法 – Hprof/jhatの使い方。仮説/検証のやり方 • パフォーマンスチューニング方法 – methodProfiling/traceViewの使い方 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-280
    • 7. トレーニングのまとめ This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-281
    • 7.1.トレーニングの振り返り • 1日目 概要 取り扱った 章 Androidアプリケーションフレームワークの主要コンポーネントを習 得 •サービス •ブロードキャストレシーバー •コンテントプロバイダ 2章 実践的開発手法を習得 •ノーティフィケーション •複数解像度 •多言語対応 •adbツール •JUnit 3章 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-282
    • 7.1.トレーニングの振り返り • 2日目 概要 取り扱った 章 実践的開発手法を習得2 •アクティビティとタスク •タスクの管理 4章 外部連帯を習得 •HTTP通信 •JSONの解析 5章 高度なデバッグを習得 •エクセプションブレークポイント •ヒーププロファイリング •メソッドプロファイリング 6章 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-283
    • 7.2. Androidに関する情報提供元 • 書籍 タイトル 著者 出版社 図解 Androidプラットフォーム開発入 門 橋爪香織 小林明大 …他 技術評論社 Google Android プログラミング入門 江川 崇 アスキー・ メディアワークス Android Hacks 株式会社ブリリア オライリー ン トサービ Android UI Cookbook for 4.0 ICS あんざい ゆき インプレスジャパ ン 入門 Android 2 プログラミング Mark Murphy 翔泳社 改訂2版 Android SDK逆引きハンドブッ ク 中西葵 , 内村祐之, シーアンドアール 高橋良司 研究所 …他 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-284
    • 7.3 Androidに関する情報提供元 • インターネット – 技術資料・ツール・ソース • Android Developers – http://developer.android.com/index.html • Open Handset Alliance – http://www.openhandsetalliance.com/ – コミュニティ • Android‐SDK‐Japan – https://groups.google.com/group/android-sdk-japan • Android Developers – http://groups.google.com/group/android-developers This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-285
    • OESF公認Androidトレーニング • アプリケーション開発 – – – – – Anroidプログラミング入門(初級) Anroidアプリケーション開発入門(初級〜中級) Anroidアプリケーション開発応用(中級〜上級) Android応用 WebAPI開発(上級) Android応用 タブレットアプリケーション開発入門( 中級〜上級) • 組み込み – Android組み込み開発 基礎コース - Armadillo-440 編 – This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-286
    • Anroidプログラミング入門 – 基本的なアプリケーション開発に必要なプログラミ ング技術を習得する NextActivity – ユーザインタフェースの使い方や画面遷移の仕方 MainActivity RequestCode:12 3 ResultCode:RESULT_OK NextActivity2 ダイアログ表示 From Result Request RequestCode:456 ResultCode RESULT_OK RESULT_CANCEL or RESULT_OK RESULT_CANCEL or Ⅰ-287 Result Cancel This material is licensed under the Creative Commons License BY-NC-SA 4.0.
    • Anroidアプリケーション開発入門 – Androidの基本的な知識から本格的なアプリケーショ ン開発 インターネットからRSS フィードを取得する メニュー 画面 インターネッ ト データベースに RSSフィードを登 録 データベース データベースからRSS フィードを検索 データベースへ登録 が完了した後、ダイ アログを表示する 一覧画面 一覧表示ボタンをク リックする This material is licensed under the Creative Commons License BY-NC-SA 4.0. 詳細画面 一覧データを 選択する Ⅰ-288
    • Anroidアプリケーション開発応用 – 入門編で作成したアプリケーションに手を加え、よ り快適なものに仕上げる – Activityのタスク管理やプロファイリングなど開発に おける高度なサイド技術の習得 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-289
    • Android応用 WebAPI開発 – 非同期処理、プロセス間通信など開発において重要 で難易度の高い技術の習得 – GAEサーバを使用した動画ダウンロードアプリケーシ ョンの開発 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-290
    • Androidタブレット開発コース • Androidタブレット開発コース – タブレット基本的な知識、新機能、開発手法のベス トプラクティスの習得 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-291
    • Android組み込み開発 基礎コース - Armadillo-440 編 – • Armdillo-440を使ったシリアルデバイスアプリケ ーション作成 シリアル Armadillo-440 ACアダプ クロスケーブル タ ( Android 2.2) 給電用USB 開発用 PC 読み取ったコードは3番 です USB-RS232C 変換ケーブル USB Grid OnputⓇ G2スキャナ RS232C LANケーブル ②Toast表示 ①メニューをタッ チ! ③ メニューの写真に This material is licensed under the Creative グリッドマークを Commons License BY-NC-SA 4.0.埋め込んだメニュー Ⅰ-292
    • Contributed By: 本ドキュメントは株式会社トップゲートが作成していま す。 http://www.topgate.co.jp 本ドキュメントは株式会社リーディング・エッジ社及び株式会社カ サレアルが Android Version up対応、オフライン環境対応のために改変していま す。 http://www.leadinge.co.jp/ http://www.casareal.co.jp/ このドキュメントの内容の一部は、Google が作成、提供しているコンテンツをベースに変更したもので、クリエイティブ・コモンズの表示 3.0 ライセンスに記載の条件に従って 使用しています。 This material is licensed under the Creative Commons License BY-NC-SA 4.0. Ⅰ-293