12. 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
22. 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
23. 2.3.サービス
• サービスとは?
– UIを持たないバックグラウンドで処理を行うコンポー
ネント
– サービスは画面とは独立して実行される。このため
、アクティビティが非表示になっても処理を続ける
音楽を再生(サービス未使用)
音楽を再生(サービス使用)
ことができる
割込み
割込み
メ
ール受信により
メ
ール受信により
中断
中断
アクティ
ビティ
アクティ
ビティ
サービス開始
再生開始
サービス
音楽再生
中断に関係なく
処理を
完了
再生開始
アクティビティから直接音楽再生した場合と、サービ
ス経由で音楽再生した場合で、メール受信によるアク
ティビティの割込みが発生した時の動作の違い
音楽再生
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-23
24. 2.3.サービス
• サービスを実装する方法
– サービスを新規作成する
– 作成したサービスをAndroidManifest.xmlに登録する
– 作成したサービスをstartServiceメソッドにて起動する
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-24
25. 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
99. 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
100. 実
習
3.1.ノーティフィケーション
実習 4
• 実習のテーマ
– サービスでRSS取得ロジックが終了した際に、ノーテ
ィフィケーションを用いて終了した旨を知らせる処
理を作成する
– ノーティフィケーションの一覧画面にて該当のノー
ティフィケーションをクリックすると、一覧画面
ロジック終
(RssListActivity)に遷移する
クリック
了
サービスとして起動
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-100
101. 実
習
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
102. 実
習
3.1.ノーティフィケーション
実習 4
– 設定情報 1
• 以下のクラス、メソッドを実装する
対象
クラス
メソッド
RSS取得
RegisterService
onStartCommand
概要
• ノーティフィケーションを表示する
• PendingIntentのフラグは0とする
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-102
103. 実
習
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
104. 実
習
3.1.ノーティフィケーション
実習 4
• 確認方法
– 「RSS取得」メニューを押す等によりRSS取得を行った
際に、以下のようなノーティフィケーションが表示さ
れる
– ノーティフィケーションの一覧から、該当のノーティ
フィケーションを押すとRSSリーダーの一覧画面に遷移
する
クリック
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-104
105. 実
習
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
106. 実
習
3.1.ノーティフィケーション
実習 4[補足]
• 実習のテーマ
– 一覧画面に遷移した際にnotificationを削除するように
する
• 実習の答え
– 別ドキュメント参照
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-106
107. 3.2. 複数解像度対応
• 複数解像度対応
– Androidではバージョン1.6より複数解像度に正式に対応している
– どのAndroid端末にインストールされるかわからない場合は、複
数解像度対応をしなければ、正しく表示されない可能性がある
– Androidがどのような仕組みで1つのアプリが複数の解像度に対
応しているのかを知っておく必要がある
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-107
109. 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
110. 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
111. 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
112. 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
113. 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
120. 実
習
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
121. 実
習
3.2.複数解像度対応
実習 5
• 確認方法
– 実習の確認ポイントを確認する
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-121
122. 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
123. 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
124. 実
習
3.3. 多言語対応
実習6
• 実習のテーマ
– エミュレータの言語設定を変更すると、それに応じ
て呼び出される文字列リソースファイルが変更され
ることを確認する
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-124
125. 実
習
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
126. 実
習
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
127. 実
習
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
128. 実
習
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
129. 実
習
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
131. 実
習
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
132. 実
習
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
133. 実
習
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
134. 実
習
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
141. 3.5.JUnit
– 各基底クラスの概要
• ActivityInstrumentationTestCase2
– ボタンを押す等の画面の操作が可能
• ActivityUnitTestCase
– アクティビティのライフサイクル上のイベント(onCreate等)を実行す
ることが可能
• ServiceTestCase
– サービスを実行することが可能
• ProviderTestCase2
– コンテントプロバイダを実行することが可能
• ApplicationTestCase
– アプリケーションのテストに利用可能
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-141
142. 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
143. 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
145. 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
146. 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
147. 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
148. 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
149. 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
152. 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
155. 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
と。
156. 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
157. 3.5.JUnit
– テストの実行方法
•
テストプロジェクトを右クリック Run as -> Android JUnit
Test を選択する
エミュレータ or 実機を接続している必要がある
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-157
159. 実
習
3.5.JUnit
実習 8
• 実習のテーマ
– JUnitのテストケースを実際に作成する
– 2つのテストケースを作成する
– 上記を通して、Androidでの単体テストの方法を習得
する
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-159
160. 実
習
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テーブルに
161. 実
習
3.5.JUnit
実習 8
• 確認方法
– テストを実行し、グリーンになる
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-161
162. 実
習
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
163. 実
習
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
164. 実
習
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
165. 実
習
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
166. 実
習
3.5.JUnit
• 実習 8[補足]
• 実習のテーマ
– 他のメソッドもテストする
This material is licensed under the Creative
Commons License BY-NC-SA 4.0.
Ⅰ-166