日々精進

新しく学んだことを書き留めていきます

android

コードをEnumに変換する

なるべくEnumクラスにコードを追加せずにコード値をEnumオブジェクトに変換するロジックを調べていたところ、以下が見つかったので採用した。 Enum と データベースの「コード値」の相互変換 - penultimate diary コード値をKey,EnumオブジェクトをValueに持…

./gradlew connectedCheckを実行すると「com.android.dex.DexException: Multiple dex files define Lorg/hamcrest/Description」エラー

原因は以下のandroidTestCompileにあった。 androidTestCompile 'junit:junit:4.11' androidTestCompile 'org.robolectric:robolectric:2.4+' Robolectric2.4がJUnit 4.8.1に依存しているがそれとは別に4.11もインストールしているためhamcrestが重複してし…

MultiDexアプリでRobolectricテストを実行すると「Caused by: java.lang.RuntimeException: Multi dex installation failed」エラー

原因はRobolectricがMultiDexアプリに対応していないため。 対応としては、テストがこける原因になっている例外を握りつぶせばよい。 具体的なやりかたは下記記事参照。 MultiDexにしたアプリケーションでRobolectricがコケる - visible true この問題はRobo…

JavaのJSONのAssertはJSONassertライブラリを使ってやると楽

JSONのAssertは文字列の比較ではやりたくないなーと思いAssertionライブラリを探したらいいのがあった。 skyscreamer/JSONassert インストールはbuild.gradleに以下を書けばOK。 androidTestCompile 'org.skyscreamer:jsonassert:1.2.+' 以下のような感じで…

assert文を有効にする

実行時引数に-eaを付ければよい。 想定外の値が来た場合にExceptionを投げるようにしてたけど、本番ビルド時にOFFにできるのでassertの方がよさそう。 参考: assert文を有効にする - tetu1984のブログ

Robolectricで実際にHTTPリクエストをサーバに送信する

Robolectric.getFakeHttpLayer().interceptHttpRequests(false); を実行した後でリクエストを送信すればよい。Robolectric便利だなぁ。 参考: Is it possible to do real http requests with robolectric

Robolectricで送信したHTTPリクエストのBodyを検証する

HTTPリクエストを送信した後、以下のようにしてBody部のStringを取得できるので、後はそれをAssertすればよい。 HttpPost sentHttpRequest = (HttpPost) Robolectric.getSentHttpRequest(0); StringEntity entity = (StringEntity) sentHttpRequest.getEntit…

Android Studioで外部ライブラリのソースコードをattachしてもソースコードが見られない

原因は謎だけど、以下手順で直った。 .idea/libraries/<ライブラリ名>.xmlを開く <CLASSES>タグ内に<root>タグが二つあったので、urlの末尾がjar!になっている方を残してタグを削除 再度attach なんで<root>が二つになってたんだろ。。</root></root></classes>

Android Studioでビルドすると文字化けする

原因は、windows環境の場合は文字コードのデフォルトがShiftJISになっていることっぽい。 Run>Edit Configurations...を選択し、Gradle taskを選択し、VM optionsに以下を入力すれば直った。 -Dfile.encoding=UTF-8 Android Applicationを選択した場合はVM o…

Android StudioでserialVersionUIDを生成する

下記記事の通りプラグインを入れると生成できた。ありがとうございます。 AndroidStudioで"serialVersionUID"を生成する - Qiita Serializableを継承しているクラス内でないと、Code -> Genarate… -> SerialVersionUID が表示されないので注意。

JavaのアサーションライブラリはAssertJが良さそう

roboletricは標準でfestをアサーションライブラリとして使っているようだけど、 festは数年前に開発が止まっている。 後継プロジェクトはAssertJらしいので、これを使うのが良さそう。 まだ使い始めだけど、読みやすくていい感じ。 AssertJ / Fluent asserti…

Androidビルド時に「generating equals/hashcode implementation but without a call to superclass」警告

原因はlombokの@Dataアノテーションを付けていること。 メッセージから、java.lang.Objectを継承していないクラスに@Dataを付けると発生するように思えるが、 java.lang.Objectを継承しているクラスでも発生したので原因は不明。。 解決策は@EqualsAndHashCo…

Javadocをエスケープするには、@literalを付ける

コメントがJavadocタグとして認識されてしまっていたので@literalをつけて回避した。 /** * @literal @EqualsAndHashCodeはコンパイル時の警告が出ないよう追加している。 * <p/> */ バックスラッシュを置くとかじゃないのか。。 参考: http://a4p.me/1092/</p/>

AndroidでJSONをparseする

普通はjacksonとか使うんだろうけど、処理するjsonが綺麗に構造化されていないので自分でparseすることにした。 JSONObjectを使うと文字列をparseしてdictionaryのような構造にしてくれる。 try { JSONObject responseJSON = new JSONObject(response); } ca…

Javaでnew Date(...)はDeprecated

new DateでDateオブジェクトを作ろうとしたらDeprecatedだよ、とIDEに怒られた。 以下のようにCalendarを使うのが正しいらしい。 new GregorianCalendar(2015, 0, 14, 15, 33, 54).getTime() 参考: Java: Why is Date deprecated, and what do I use instea…

Androidでテストを実行すると「The method assertEquals(Object, Object) is ambiguous for the type」エラー

以下のようにassertしようとすると、エラーが出た。 Assert.assertEquals(false, actuals.get(0).getIsVisible()); 原因は上記コードがassertEquals(Object, Object)ともassertEquals(Boolean, Boolean)とも解釈できるため。以下のようにして型を明示すると…

Robolectricでファイルからテストデータを読み込んでテストする

手順は以下。 以下の記事に書いてあるとおりコードを実装する。 Robolectricのテストケースでassetsからファイルを読み込む - Qiita src/test/ 下にAndroidManifest.xmlをコピーする src/test/assets 下にconfig.propertiesをコピーする これでテストデータ…

Androidのjacksonをインストールすると「Duplicate files copied in APK META-INF/LICENSE」エラー

エラーメッセージから想像するに、複数のjarに同名のファイルが含まれていることが原因っぽい。 重複しているのは不要なファイルなので、ビルドオプションで除いてやるとよい。 これはjacksonのバグだけど、2.3ではまだ直ってないようだ。 android { ... pac…

Androidでファイルから文字列を読み込んでStringにする

InputStreamのtoString()とかで出来るかと思ったら、ちょっと面倒だった。 以下のようにBufferedReaderを回して文字列を結合しないといけない。 もっと簡単にできる方法ないのかな? BufferedReader r = new BufferedReader(new InputStreamReader(inputStre…

roboletricでテスト実行時にbreakpointで止まるようにする

Preferences>Complier>Use in-process buildのチェックを外すとbreakpointで止まるようになる。 後はRun/Debug Configurationsの中の[test]が後ろに付いているConfiguration(これは自動生成されるっぽい)を選択してDebug実行を開始すればよい。 Android St…

Android Studioでassetsフォルダを追加する

以下手順で追加できる。 appフォルダを右クリックし、New>Folder>Assets Folderを選択する。 次の画面でFinishをクリックする。 参考: Where to place Assets folder in Android Studio

roboletricでテストを実行すると「org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException」エラー

原因はroboletricが実行時にmaven repositoryから何かをダウンロードしようとするがプロキシ設定がされていなくてmaven repositoryにアクセス出来ないため。 プロキシ設定は~/.m2/settings.xmlに以下のように書く。 <settings> <proxies> <proxy> <active>true</active> <protocol>http</protocol> <host>proxy.somewhere.com</host> <port>8080</port> <username>p</username></proxy></proxies></settings>…

Android Studioをコマンドラインから起動する

環境はMacです。 Android StudioのメニューのCreate Command-line Launcherを実行し、 studioコマンドを生成する。 以下のコマンドでAndroid Studioを起動できる。 studio <androidプロジェクトのプロジェクトルートパス> 以下でもOK。 open -a "Android Studio" <androidプロジェクトのプロジェクトルートパス> Android StudioはXCodeのxcworkspaceのよ</androidプロジェクトのプロジェクトルートパス></androidプロジェクトのプロジェクトルートパス>…

./gradlew buildを実行すると「SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable.」エラー

原因はlocal.propertiesがプロジェクトルートに無いこと。 local.propertiesを作り、中身を以下のようにすればよい。 ## This file is automatically generated by Android Studio. # Do not modify this file -- YOUR CHANGES WILL BE ERASED! # # This fil…

Android Studio用.gitignoreファイル

以下を.gitignoreに書けばOK。 ググるともっと沢山指定している例が多かったが、それは大抵Eclipse用で、 Android Studioになってからは大分シンプルになったようだ。 .gradle /local.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build 参…

Androidエミュレータを起動すると「emulator: Failed to sync vcpu reg」エラー

よくある原因はGenymotionが起動中であることだけど、Genymotionは起動していなかった。 原因は、Android AVD Managerが応答しない状態になっていたこと。 アクティビティモニタからAndroid AVD Managerを強制終了すると直った。 参考: How do I fix "Faile…

Android Studioでlombokで生成したgetter,setterを解決できない

補完されなかったり、メソッド名が赤字になったりして困っていた。 lombok pluginを入れると直った。 こういうエコシステムも一から勉強していかないとなぁ。。 参考: http://rejasupotaro.github.io/2014/04/30/45.html

gradlewを実行すると、「Could not find property 'processResources' on com.android.build.gradle.internal.api.ApplicationVariantImpl_Decorated」エラー

原因はgradleの仕様変更。 build.gradleを以下のように修正すると直った。 androidManifestFile variant.outputs[0].processResources.manifestFile 参考: http://rx93g.blogspot.jp/2014/12/android-studio-10.html

gradlewを実行すると、「Error:Could not find property 'processManifest' on com.android.build.gradle.internal.api.ApplicationVariantImpl_Decorated」エラー

原因はRobolectric Gradle Pluginのバージョンが古いこと。 Android Studioのバージョンを1.0.0に上げると、Robolectric Gradle Pluginは1.4にしないといけないらしい。 以下のようにバージョンを指定すると直った。 classpath 'org.robolectric:robolectric…

gradlew実行時に「No such property: projectDependencies for class: com.android.build.gradle.internal.api.ApplicationVariantImpl_Decorated」エラー

Android Gradle pluginのバージョンとandroid-aptのバージョンが合っていないことが原因。 以下のようにバージョンを修正すると直った。 classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4' classpath 'org.robolectric:robolectric-gradle-plugin…