Android Gradle Pluginを4.0.0から4.0.1へアップデート ( Android11 の Package visibility )
Android Gradle Pluginのバージョン4.0.0から4.0.1へアップデート。何が変わったのでしょうか? https://developer.android.com/studio/releases/gradle-plugin#4-0-0
This minor update supports compatibility with new default settings and features for package visibility in Android 11.
Package visibilityの管理ができるようになりました!
なんだそれは?調べてみると、他のアプリとの連携を細かく制御できるようです。 developer.android.com
- Managing package visibility | Android Developers
- Configuring package visibility based on use cases | Android Developers
アプリのtargetがAndroid 11 (API Level 30)以上で、他のアプリと連携したい場合、manifestファイルに <queries>
という要素を書かないといけない場合ができたようです。
例えば、PackageManagerで情報を取得するケースを試してみます。
targetSdkVersion 30
のアプリA ( info.bati11.example.a
)とアプリB ( info.bati11.example.b
) を用意する。アプリAからPackageManagerを使ってアプリBの情報を取得してみることにする。
package info.bati11.example.a class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) findViewById<Button>(R.id.button).setOnClickListener { val packageName = "info.bati11.example.b" Log.i( "test", packageManager.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES).toString() ) } } }
API Level29のエミュレータで試すと問題なし。
2020-09-14 23:50:27.850 5962-5962/info.bati11.example.a I/test: PackageInfo{19d4329 info.bati11.example.b}
API Level30のエミュレータで試すと以下のExceptionが発生!
2020-09-14 23:59:17.151 5734-5734/info.bati11.example.a E/AndroidRuntime: FATAL EXCEPTION: main Process: info.bati11.example.a, PID: 5734 java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) Caused by: android.content.pm.PackageManager$NameNotFoundException: info.bati11.example.b at android.app.ApplicationPackageManager.getPackageInfoAsUser(ApplicationPackageManager.java:206) at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:178) at info.bati11.example.a.MainActivity$onCreate$1.onClick(MainActivity.kt:20) at android.view.View.performClick(View.java:7448) at android.view.View.performClickInternal(View.java:7425) at android.view.View.access$3600(View.java:810) at android.view.View$PerformClick.run(View.java:28305) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
アプリAのAndroidManifest.xmlに <queries>
を記述してみる。
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="info.bati11.example.a"> <queries> <package android:name="info.bati11.example.b" /> </queries> ...
これでAPI Level30のエミュレータでもOK!
2020-09-15 00:13:56.601 2388-2388/info.bati11.example.a I/test: PackageInfo{7ea0aab info.bati11.example.b}
ちなみに、アプリAの targetSdkVersion
を 30
から 29
に変えれば例外は発生しませんでした。
また、 startActivity
でアプリAからアプリBを起動する場合に <query>
は必要なかったです。
公式ドキュメントにも記載されてますね。
https://developer.android.com/training/basics/intents/package-visibility#automatic
Note: If your app targets Android 10 (API level 29) or lower, all apps are visible to your app automatically.
...
In addition, you can start another app's activity using either an implicit or explicit intent, regardless of whether that other app is visible to your app.
シェルソートの動きを見てみる
Aizu Online Judge の Shell Sort の問題 をやってて、なんか分かった気がしないなぁと思ってました。
Aizu Online Judgeの一部の問題は、本だと解説されてたりします。
計算量もどうしたらいいんだろと調べたところ、単純ではないようです。
まずは雰囲気だけでもサクッと...と思ってJavaScriptで挿入ソートとシェルソートを並べてみました。うむ、確かにシェルソートの方が速くソートできてる。
See the Pen Insertion Sort & Shell Sort by kariyayo (@kariyayo) on CodePen.
記念日を忘れないためのAndroidアプリをつくった
以前、記念日を忘れないためのWebアプリを作りました。
しかし、致命的な弱点がありました。それはオンラインじゃないと動かないということです。つまり、飛行機で上空にいるタイミングで「もう少しで結婚記念日だわね〜」みたいな会話になった時に、何年目だっけ!?というのをすぐに確認できません!!!
というわけでAndroidアプリとしてオフラインで動くように作りました。あと通知でリマインドする機能も追加。これでばっちりです。
開発メモ
という理由に加えて、2020年になってから久しぶりに仕事でもガッツリとAndroidアプリ開発に携わることにもなったので、練習がてら作り初めてみたのです。
久しぶりのAndroidアプリ開発は、以前と比べてとても快適になっていました。これまでにもいろいろなアーキテクチャやコンポーネントがありましたが、2020年時点では Jetpack というラベル付けで提供されるものを使うと良さそうです。
快適とはいえ学ぶことは多かったので、どんなことを調べたっけなというのをメモ。
Kotlin
プログラミング言語はJavaではなくKotlinになってる。Kotlin Bootcamp Courseというcodelabをやりつつ公式ドキュメントを参照するというのをやった。Kotlin イン・アクション という本も読んだけどKotlinのバージョンが古いので、こちらも公式ドキュメントを参照しながら。特にCoroutine周りは公式ドキュメントが読みながらコード書いてみるのが良い。
- Reference - Kotlin Programming Language
- codelab: Kotlin Bootcamp Course
- [asin:B076Q2L1M6:title]
- Coroutins Guide
Jetpack
Kotlinを使ったAndroidアプリ開発のcodelabをやった。Jetpackコンポーネントも使いつつなので良い。
Android KTXを使うといろいろ便利。以下をよく使う。
codelabが終わったらすぐに以下の記事を読んでおけばよかった。
Dagger
DIコンテナ。Android DevelopersにもDaggerのページがあるし、codelabも用意されているのでデファクトスタンダード感。これらのドキュメントのViewModelはJetpackのViewModelではないのでちょっと混乱した...
- Dependency injection in Android | Android デベロッパー | Android Developers
- codelab: Using Dagger in your Android app - Kotlin
Dagger単体ならまだしもAndroidと合わせて使うと難しい。この本読みながらいろいろ試行錯誤した。
DaggerのAndroid拡張はドキュメントや本を読んでもスッと入ってこない。SubComponentを良い感じに取り扱う方法は結局よく分からず。
テスト
テストはユニットテストをちょっとしか書けていない。ViewModelとLiveDataを使ったテストは難しい。。いろいろ読み漁った。
- codelab: Advanced Android in Kotlin 05.1: Testing Basics
- Android Architecture Componentとテスト2019年7月版 / Testing Android Architecture Components in 2019-07 - Speaker Deck
- Easy Coroutines in Android: viewModelScope - Android Developers - Medium
- kotlinx-coroutines-test
- LiveDataのUnitTest - Kenji Abe - Medium
しかもJUnit5を普通に使うだけだとうまくいかないのを解決できずJUnit4を使ってる。Androidのコンポーネントに依存しないテストはJUnit5で書くなどして、バージョン4と5が混在しても大丈夫。あんまり覚えてないけど、この記事ぱらぱらと読んだ気がする...。
モックライブラリのMockKは使いやすいと思った。
一覧画面
codelabには出てこないけどやりたかったこと。
スクロールするとUIにないデータを取りにいくという処理はpagingを使う。
スクロールに応じてToolbarやFloating Action Buttonを動かすにはCoodinateLayoutを使う。
UIの細かいところ
角丸にするのがよく分からなかったり...
リップル対応したり...
アイコン
こちらを使って W
の1文字で...
ライセンス表記
使用しているライブラリのライセンス表示はこちらを使って。
開発中のデバッグ
このスライドがとても参考になった。
おしまい
Androidは自分のためのアプリをつくって日常で使えて良いですね!