ラベル Android Studio の投稿を表示しています。 すべての投稿を表示
ラベル Android Studio の投稿を表示しています。 すべての投稿を表示
2015/01/26

[Android] Support Library に追加された testing-support-lib や Espresso 2.0 で JUnit4 な Android のテストを書く

Android Support Library に UI テストを行う Espresso 2.0 や
JUnit4 でテストを行うための testing-support-lib が追加されました。

前置き

概要とドキュメントなど

Espresso 2.0 is here!

android-test-kit - Google's Testing Tools For Android - Google Project Hosting


サンプルコード

googlesamples/android-testing


関連エントリ

Espresso 2.0 が Android support library の一部としてリリースされた - ひだまりソケットは壊れない
Espressoがsupport libraryになってAndroidでJUnit4が使えるようになったと聞いたので試してみた - みんからきりまで
続・AndroidでJUnit4を使う方法(Android SDKで正式サポートされました!) - Qiita
support packageに追加されたtesting-support-libを使ってAndroidのテストをJUnit4で書く - visible true


JUnit4 で Activity のテストを書いてみる

@@ -10,6 +10,8 @@ android {
         targetSdkVersion 21
         versionCode 1
         versionName "1.0"
+        // testing
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
     }
     buildTypes {
         release {
@@ -17,9 +19,16 @@ android {
             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
         }
     }
+    packagingOptions {
+        exclude 'LICENSE.txt'
+    }
 }

 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
     compile 'com.android.support:appcompat-v7:21.0.3'
+    // testing
+    compile 'com.android.support:support-annotations:21.0.3'
+    androidTestCompile 'com.android.support.test.espresso:espresso-core:2.0'
+    androidTestCompile 'com.android.support.test:testing-support-lib:0.1'
 }
package com.wada811.android.junit4;

import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.test.ActivityInstrumentationTestCase2;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.notNullValue;

@RunWith(AndroidJUnit4.class)
public class MainActivityTest extends ActivityInstrumentationTestCase2 {

    private MainActivity activity;

    public MainActivityTest(){
        super(MainActivity.class);
    }

    @Before
    public void setUp() throws Exception{
        super.setUp();
        injectInstrumentation(InstrumentationRegistry.getInstrumentation());
        activity = getActivity();
    }

    @After
    public void tearDown() throws Exception{
        super.tearDown();
    }

    @Test
    public void checkPrecondition(){
        assertThat(activity, notNullValue());
        assertThat(getInstrumentation(), notNullValue());
    }

}

参考

Getting Started - EspressoSetupInstructions - android-test-kit
AndroidJUnitRunnerUserGuide - android-test-kit

テストを実行する

./gradlew connectedAndroidTest コマンドを実行

端末もしくはエミュレータでテストを実行することができます。
しかし、何故か MainActivityTest.java は実行されませんでした。
JUnit3 なテストは実行されていますが、 JUnit4 な テストは実行されないみたいです。

プロジェクトエクスプローラで右クリックから Run...

ファイルを指定して実行すれば JUnit4 なテストも実行できます。


Edit Configurations... から Android Test を追加してクラスを指定して実行

クラス(ファイル)を指定して実行すれば JUnit4 なテストも実行できます。
All in Module や All in Package では JUnit4 なテストは実行されませんでした。


クラスを指定しなくても JUnit4 なテストを実行したい

これは偶然なのか考えられているのかわからないけど Jake 神の ActivityRule を使うと
直接クラスを指定しなくてもテストを実行できるようになります。
package com.wada811.android.junit4;

import android.support.test.runner.AndroidJUnit4;
import com.jakewharton.test.ActivityRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static android.support.test.espresso.Espresso.*;
import static android.support.test.espresso.assertion.ViewAssertions.*;
import static android.support.test.espresso.matcher.ViewMatchers.*;
import static org.hamcrest.Matchers.*;

@RunWith(AndroidJUnit4.class)
public class MainActivityTestWithRule {

    @Rule
    public final ActivityRule activityRule = new ActivityRule<>(MainActivity.class);

    @Test
    public void checkPrecondition(){
        // MatcherAssert.assertThat(activityRule.instrumentation(), Matchers.notNullValue());
        assertThat(activityRule.instrumentation(), notNullValue());
    }

    @Test
    public void showHelloWorld(){
        // Espresso.onView(ViewMatchers.withId(R.id.textView)).check(ViewAssertions.matches(ViewMatchers.withText(R.string.hello_world)));
        onView(withId(R.id.textView)).check(matches(withText(R.string.hello_world)));
    }

}
Espresso 2.0 でテストを書いてみました。
クラス名を覚えるのは辛い感じなので static import でメソッド書くだけにしたい感じがあります。

ソースコードは wada811/Android-JUnit4 にあります。
Activity だけじゃなく他のテストについても増やしていきたいです。

参考

A JUnit @Rule which launches an activity when your test starts. Stop extending gross ActivityInstrumentationBarfCase2!
2014/10/24

AndroidStudio で APK を特定のフォルダにコピーする Gradle の設定

AndroidStudio で APK のファイル名を変更する Gradle の設定 | DevAchieve
APK をリネームしましたが、
出力されるフォルダが build/outputs/apk/ なので
変更したいことがあるかと思います。
Gradle の Task を定義してあげれば
任意のフォルダにコピーする処理を実行することができます。

Gradle で Signed APK とProGuard 関連ファイルをコピーするタスクを設定する


Add move apk task and move proguard task · c7cdd90 · wada811/Android-Material-Design-Colors

applicationVariants.all { variant ->
    if (variant.buildType.name.equals("release")) {
        variant.outputs.each { output ->
            if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) {
                // Rename APK
                def applicationId = defaultConfig.applicationId
                def versionCode = defaultConfig.versionCode
                def versionName = defaultConfig.versionName
                def date = new java.text.SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())
                def newName = "${applicationId}_r${versionCode}_v${versionName}_${date}.apk"

                def publish = project.tasks.create("publishAll")

                // Move and Rename APK
                def task = project.tasks.create("publish${variant.name.capitalize()}Apk", Copy)
                task.from(output.outputFile)
                task.rename(output.outputFile.name, newName)
                task.into(file("${variant.name}/apk").getAbsolutePath())

                task.dependsOn variant.assemble
                publish.dependsOn task

                // Move ProGuard
                if (variant.buildType.runProguard) {
                    def copyTask = project.tasks.create("copy${variant.name.capitalize()}MappingText", Copy)
                    def buildTypeName = variant.buildType.name
                    copyTask.from(file("build/outputs/proguard/${buildTypeName}").path)
                    copyTask.into(file("${variant.name}/proguard").getAbsolutePath())

                    copyTask.dependsOn variant.assemble
                    task.dependsOn copyTask
                }
            }
        }
    }
}

実行

./gradlew publishAll
app/release/apk/ に Signed APK が、
app/release/proguard/ に ProGuard 関連ファイルがコピーされます。

参考

AndroidStudioでAPKを作ったあとに特定のディレクトリにAPKをコピーする - Qiita
2014/10/23

AndroidStudio で APK のファイル名を変更する Gradle の設定

Android Studio で Sigined APK を生成するには
ツールバーの [ Build > Generate Signed APK... ] から
ガイダンスに従えば生成できます。
しかし、GUI からではファイル名は app-release.apk などになるので
変更したい場合などは Gradle の設定が必要になります。

Gradle で Signed APK のファイル名を設定する

Generate signed APK has been named by program · bc41551 · wada811/Android-Material-Design-Colors

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.0.1"

    defaultConfig {
        applicationId "at.wada811.android.material.design.colors.sample"
        minSdkVersion 8
        targetSdkVersion 21
        versionCode 2
        versionName "1.1.0"
    }
    signingConfigs {
        release
    }
    buildTypes {
        release {
            runProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }

    applicationVariants.all { variant ->
        if (variant.buildType.name.equals("release")) {
            def file = variant.outputFile
            def applicationId = defaultConfig.applicationId
            def versionCode = defaultConfig.versionCode
            def versionName = defaultConfig.versionName
            def date = new java.text.SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())
            def newName = "${applicationId}_r${versionCode}_v${versionName}_${date}.apk"
            variant.outputFile = new File(file.parent, newName)
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21+'
    compile project(':library')
}

./gradlew assembleReleaseすると
at.wada811.android.material.design.colors.sample_r2_v1.1.0_20141022_173737.apk
のようなファイル名で app/build/outputs に生成されます。

参考

gradle - AndroidStudioでAPKのファイル名にバージョン番号などを入れる設定 - Qiita

追記: Android Gradle Plugin 0.13, Gradle 2.1 で outputFile が deprecated になっている

WARNING [Project: :sample] variant.getOutputFile() is deprecated. Call it on one of variant.getOutputs() instead. が表示されるので書き直しました。

applicationVariants.all { variant ->
    if (variant.buildType.name.equals("release")) {
        variant.outputs.each { output ->
            System.println("* output.outputFile.name : ${output.outputFile.name}")
            if (output.outputFile != null && output.outputFile.name.endsWith('.apk')) {
                // Rename APK
                def applicationId = defaultConfig.applicationId
                def versionCode = defaultConfig.versionCode
                def versionName = defaultConfig.versionName
                def date = new java.text.SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())
                def newName = "${applicationId}_r${versionCode}_v${versionName}_${date}.apk"
                output.outputFile = new File(output.outputFile.parent, newName)
            }
        }
    }
}

outputs というから複数あるのかとおもいきや apk しかありませんでした。
無駄にネストが深くなる…。

参考

android - Gradle warning: variant.getOutputFile() and variant.setOutputFile() are deprecated - Stack Overflow
2014/10/22

AndroidStudio で APK の署名の設定を gradle.properties に記述する

Android Studio で Sigined APK を生成するには
ツールバーの [ Build > Generate Signed APK... ] から
ウィザードに従えば生成できます。
しかし、CUI から Signed APK を生成したいことがあるかと思います。
また、そのプロジェクトを public リポジトリで管理している場合に
署名に関する設定を公開しないようにするにはどうすればいいのかという問題もあります。

以下に示す方法では、証明に関する設定を gradle.properties に記述し、
.gitignore で gradle.properties を公開しないようにすることで
署名に関する情報を秘密にしておくおことが可能です。

Generate signed APK has been named by program · bc41551 · wada811/Android-Material-Design-Colors

apply plugin: 'com.android.application'

android {
    compileSdkVersion 21
    buildToolsVersion "21.0.1"

    defaultConfig {
        applicationId "at.wada811.android.material.design.colors.sample"
        minSdkVersion 8
        targetSdkVersion 21
        versionCode 2
        versionName "1.1.0"
    }
    signingConfigs {
        release
    }
    buildTypes {
        release {
            runProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
    }
}

...

if (project.hasProperty('storeFile')) {
    android.signingConfigs.release.storeFile = new File(System.getenv('HOME'), storeFile)
}
if (project.hasProperty('storePassword')) {
    android.signingConfigs.release.storePassword = storePassword
}
if (project.hasProperty('keyAlias')) {
    android.signingConfigs.release.keyAlias = keyAlias
}
if (project.hasProperty('keyPassword')) {
    android.signingConfigs.release.keyPassword = keyPassword
}

storeFile=/path/to/your.keystore
storePassword=keystorePass
keyAlias=appAlias
keyPassword=appPass

gradle.properties

new File(System.getenv('HOME'), storeFile) がキモで、
file(storeFile) にするとプロジェクトの相対パスで認識されるから
プロジェクトに keystore を含めるか、無理やり相対パスからたどるかになるんだけど
前者はプロジェクトごとに keystore を入れなければならなくて一元管理できないし、
後者は環境によってパスが変わりうるから微妙になります。
その点、new File(System.getenv('HOME'), storeFile) は $HOME からの絶対パスになるので統一しやすいです。

参考

AndroidStudio - Android Studio(Gradle)でapkファイルを作成する時にstorePassword/keyAlias/keyPasswordの指定方法をいくつか検証してみた。 - Qiita
2014/09/12

[Android]ライブラリプロジェクト(aar)をMavenリポジトリとしてGitHubで配布する

Androider の皆さんこんにちは。
もう Eclipse から Android Studio への移行は済みましたか?
僕はまだ途中です。
俺々ライブラリが移行できないと Android Studio に移行できないので
今回はそのための手順をご紹介したいと思います。

環境

OS
Mac OS X 10.8.5
Android Studio
0.8.9

ライブラリプロジェクト(aar)とは

Android Studio 、というより Android Studio で導入された Gradle というビルドシステムでの
ライブラリプロジェクトの配布用バイナリ形式を aar (Android archive) と呼ぶらしいです。
.aar の拡張子を持つ ZIP ファイルで、以下が入っています。
  • /AndroidManifest.xml (必須)
  • /classes.jar (必須)
  • /res/ (必須)
  • /R.txt (必須)
  • /assets/ (オプション)
  • /libs/*.jar (オプション)
  • /jni//*.so (オプション)
  • /proguard.txt (オプション)
  • /lint.jar (オプション)
参考: AAR Format - Android Tools Project Site

配布編

まずは Android Studio でライブラリプロジェクトを作成します。詳しい方法については割愛。

試しに aar を作成するためリリースビルドするため、
上の画像の Terminal で ./gradlew assembleRelease を実行します。
以下のコマンドで aar が作成されているか確認します。
find . -name '*.aar'
./library/build/outputs/aar/library.aar

問題ないので build.gradle に Maven プラグインを使用して aar やら何やらを生成するタスクを追記します。
以下のハイライト部分です。
(余談だけど build.gradle って説明された時に初めは root の build.gradle なのか
Modules の build.gradle なのかわからなくて戸惑いました。だいたい Modules の方らしい。)
apply plugin: 'com.android.library'

android {
    compileSdkVersion 19
    buildToolsVersion "20.0.0"

    defaultConfig {
        minSdkVersion 10
        targetSdkVersion 19
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:20.0.0'
}

def repo = new File(rootDir, "repository")

apply plugin: 'maven'

uploadArchives {
    repositories {
        mavenDeployer {
            repository url: "file://${repo.absolutePath}"
            pom.version = '1.0.0'
            pom.groupId = 'at.wada811'
            pom.artifactId = 'android-dialog-fragments'
        }
    }
}
pom.version がライブラリのバージョン、
pom.groupIdが自分用の識別子(Java の package 名の最初の部分で良さそう)、
pom.artifactIdがライブラリの識別子、みたいです。
詳しくは 第52章 Mavenプラグイン を読んで下さい。

追記したら Android Studio の Terminal で ./gradlew uploadArchivesすると
repository ディレクトリに aar が生成されます。
tree repository
repository
└── at
    └── wada811
        └── android-dialog-fragments
            ├── 1.0.0
            │   ├── android-dialog-fragments-1.0.0.aar
            │   ├── android-dialog-fragments-1.0.0.aar.md5
            │   ├── android-dialog-fragments-1.0.0.aar.sha1
            │   ├── android-dialog-fragments-1.0.0.pom
            │   ├── android-dialog-fragments-1.0.0.pom.md5
            │   └── android-dialog-fragments-1.0.0.pom.sha1
            ├── maven-metadata.xml
            ├── maven-metadata.xml.md5
            └── maven-metadata.xml.sha1
この repository を GitHub に Push すれば配布側の手順としては完了です。

利用編

GitHub で配布されているライブラリプロジェクト(aar) を参照することで利用することができます。
プロジェクトは準備出来ているとして、app などの build.gradle に以下を記述します。
repositories {
    maven { url 'http://raw.github.com/wada811/Android-DialogFragments/master/repository/' }
}

dependencies {
    compile 'at.wada811:android-dialog-fragments:1.0.0'
}
全体は HelloGradle/build.gradle at master · wada811/HelloGradle を見て下さい。
読み込めると以下のように app/build/intermidiates/exported-aar/ 以下に追加されます。


これで Public な俺々ライブラリが手軽に配布、参照できて便利ですね!

参考

u1aryzの備忘録とか: githubをMavenリポジトリとしてAndroidライブラリプロジェクト(aar)をデプロイして使用する
2014/09/10

Android Studio で support library のソースコードをアタッチする

Android Studio でサポートライブラリのソースコードが読めなくて困ったので調べると
サポートライブラリのソースコードを別途ダウンロードして設定が必要でした。

参考
Android Studio - Attach Source - web系な備忘録

cd $ANDROID_SDK_HOME/extras/android
git clone https://android.googlesource.com/platform/frameworks/support/ support-src

FragmentActivity などを command + B で開いて
右上の Attach Source... をクリックして
$ANDROID_SDK_HOME/extras/android/support-src を指定してあげれば
サポートライブラリのソースコードを読めるようになります。
2014/05/22

Android Studio のエディタのタブを切り替えるショートカットキー

Android Studio カスタマイズシリーズ第二弾。
Android Studio のエディタのタブを次のタブ、前のタブに切り替える
ショートカットキーを Sublime Text 2 と一致させたいと思います。

[Preference > Keymap] を開いて Tab で検索。

Select Next Tab: command + shift + ]
Select Previous Tab: command + shift + [

上記のように設定されているが、実際の動きはそうなっていません。

なぜなのか

Keymap shows characters for keys only for english keyboard layout correctly : IDEA-63779
Android Studio のベースである IntelliJ IDEA のバグで Keymap が
US キーボードの配置に依存しているようで
JP キーボードでは記号系の紐付きがおかしくなっているからのようです。
エディタでの入力はタイプしたものが見たままそのまま表示されますが、
Keymap のショートカットキー登録の部分だけが入力したものと異なるキーが表示されます。

[ を入力したら ] と、] を入力したら \ と表示されます。

どうすればいいのか

見た目上は異なるキーですが、結局入力したキーで反応するので

Select Next Tab: command + shift + ]
Select Previous Tab: command + shift + [

上記のように入力して以下のように表示されていれば良いです。

Select Next Tab: command + shift + [
Select Previous Tab: command + shift + \

このバグは混乱するので直して欲しいです。かなり放置されているので期待は薄そうですが…。
2014/05/21

Android Studioでカーソルをワード区切り単位で移動する

Android Studio が使いにくいです。
カーソル移動もままなりません。
これが IDE の移行コストか…と思いながら Keymap を眺める日々です。

さて、愚痴はこのへんにして Android Studio を調教していきましょう。

Android Studio のデフォルトの挙動では alt + , alt +
ワード単位で移動してしまいます。

これ↑をこう↓したいわけです。


どうすればいいのか?

[Preference > Keymap] で 検索バーに [ Move Caret Word Different ] を入力すると
以下の項目が見つかるかと思います。(検索バーの右のボタンを押せばショートカットキーからも検索できます)
Move Caret to Next Word in Different "Camel|Humps" Mode
Move Caret to Previous Word in Different "Camel|Humps" Mode
この項目で右クリックして [ Add Keyboard Shortcut ] を選択後、
割り当てたいショートカットキーを入力します。
ショートカットキーが衝突した場合は既存のショートカット設定を削除して上書きすることができます。

こうして僕は alt + , alt + を設定して幸せになれました。

上記の動きで文字列を選択したい

以下の項目に alt + shift + , alt + shift + を割り当てました。

Move Caret to Next Word with Selection in Different "Camel|Humps" Mode
Move Caret to Previous Word with Selection in Different "Camel|Humps" Mode

2014/05/20

Android Studioのカラーテーマを変更/追加する

Android Studio といえばクールなダークテーマですよね?
ただでさえ新しいビルドシステム Gradle が導入され、
Android Studio で開発 イコール カッコイイ なのに
ダークテーマだなんてかっこ良すぎると思います。

羨ましいので Android Studio を導入してみたところ
別に普通のライトグレーな普通にテーマでした。
あれ?と思いつつ、調べたところ
Android Studio のイメージのクールなダークテーマは
[Preference > Appearance] の Theme で Darcula を設定すれば適用されます。

Appearance を Darcula すると自動的に エディタのカラーテーマも Darcula になるようです。
オレンジ系のカラーテーマはそんなに好きじゃなかったので
Themes for InteliJ IDEA, PhpStorm, PyCharm, RubyMine, WebStorm and AppCode. から
Monokai Sublime Text 3 というカラーテーマをダウンロードしてきました。
Android Studio の [File > Import Settings...] から読み込めばカラーテーマを追加できます。
エディタのカラーテーマは [Preference > Editor > Colors & Fonts] から変更できます。

なんでこれくらいのこと Eclipse でもやってなかったんだろうと思ったら
Eclipse はエディタ部分は変更できても Appearance が変更できないからやめたようです。
like Darcula - Kazzzの日記
Eclipse より Android Studio の方がイケてますね。完全に移行できるよう頑張ります。


参考

第3回 はじめましてのAndroidアプリケーション:Android Studio最速入門~効率的にコーディングするための使い方|gihyo.jp … 技術評論社
How to change or add theme to Android Studio? - Stack Overflow
Color Themes & Fonts
2014/05/17

MacでAndroid Studioが起動できない

JDK6 が入っていない

Brewfile + Homebrew + Homebrew-caskで Mac の環境構築をする | DevAchieve
Brewfile に以下のように記述しているから問題ないはず…!
cask install --appdir=/Applications java


と思ったら Android Studio をダブルクリックをしても反応がない…屍のようだ…

Android Studio.app/Contents/MacOS/studio を直接実行してみると
以下の様なエラーメッセージが出ていました。
JavaVM FATAL: Failed to load the jvm library.

どうやら Mac 版 Android Studio は JDK6 が必要なようです。
参考: Google Play Services SDK のセットアップ(Android Studio) - Qiita

以下のように記述して brew bundle ~/Brewfile を実行したら起動できました。
tap caskroom/versions

# JDK6/JDK7 for Android Studio
cask install --appdir=/Applications java7
cask install --appdir=/Applications java6

タグ(RSS)