20190526のAndroidに関する記事は14件です。

ジャイロで視差効果 (uGUI、2D)

できること

  • Unityの2Dプロジェクト、または、3Dプロジェクトでも、常に最前面に張り付くタイプ(Screen Space - Overlay)のuGUIで、スクリプトなしで簡易的な視差効果を実現します。

アセットの入手 (GitHub)

ダウンロード ⇒ ParallaxEffect.unitypackage
ソースはこちらです。

挙動と例

デバイスを傾けると、向きと傾きに応じて、オブジェクトがスライドします。
同時に、複数のオブジェクトに対して、個別の設定で効果を付与できます。
ScreenRecord-_10_46午後_-5月-26_-2019__2.gif   inspecter.png

解説

この例では、大きさの異なる4枚の矩形を中心を合わせて配置し、それぞれにコンポーネントをアタッチして、大きいものから順に「Deepness=1~4」で設定しています。(他のパラメータはデフォルトのままです。)
※この例のシーンがアセットに付属しています。

使い方

  • プロジェクトにアセットをインポートしてください。
  • 対象のオブジェクト(Imageやスプライト)に、"ParallaxEffect"スクリプトをアタッチしてください。
  • インスペクタでパラメータを調整してください。
  • 通常、Editor上ではジャイロが機能しないので、動作の確認には実機が必要です。
パラメータ 意味
ShiftRatio 傾きに反応する感度です。逆向きにスライドさせる場合は負数を指定します。
Deepness 感度に乗じられます。
Movable Radius スライドを制限する距離を指定します。0を指定すると制限されません。
Return Ratio 中点に復帰する速度を指定します。0を指定すると自動復帰しなくなります。
Horizontal 水平方向のスライドについて有効/無効を切り替えます。
Vertical 垂直方向のスライドについて有効/無効を切り替えます。

ParallaxEffect.Reactable = ture; // or false … 全体の有効/無効を切り替えます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

スマホでScratchのゲームを作る3つのコツ

もう試されている方もおられると思いますが、なんとScratch は、PCを一切使わずにスマホだけでもプログラムが作れますね!

実際に作ったゲームとプログラムはこちらから。
https://scratch.mit.edu/projects/311751784/

僕は、アンドロイド Xperia XZ2 を使っていますが、以下の3つのことに気づいたことで、電車の中で立ちながらでもゲームが作れるようになりました。どんなスマホでもできるかはわからないのですが、興味ある方試してみてください。

コツ1:拡大縮小が可能な領域を意識する

スマホの画面は小さいので、拡大・縮小・スクロールを頻繁に行うことになります。

しかし、ブロックを配置する領域でピンチやスワイプしても、そのブロック領域での操作となってしまい、全体の拡大縮小はできません。

しかし、図で示した領域ならその操作が可能です。この領域を常に確保できるように意識しながら拡大・縮小・スクロールをします。

01_全体図2.png

コツ2: ブラウザの設定(PC版サイト)のチェックを切り替える

拡大を不用意にやってしまうと、コツ1で示した領域が画面のどこにもない状態となり、戻れなくなってしまうことがあります。そんなときは、右上のブラウザ(Chromeの場合)のメニューから「PC版サイト」にチェックを入れ、画面の表示を変えます。すると拡大縮小可能領域にたどり着ける場合があります。うまくいったら、PC版サイトのチェックは外します(スマホ版の方が全体的に操作がしやすいです)。どうしてもだめな場合には、、、再読み込みします。

02_メニュー1.png

コツ3: 画面上に操作ボタンをつくる

当然ですが、スマホにはカーソルキーがありません。しかし、その代わりに画面上にボタンを作って代用することができます。

例えば、次の図のように、ballというスプライトを画面右下に配置し、「このスプライトが押されたとき、メッセージ1を送る」などとします(タッチでスプライト位置がずれないように、位置合わせのブロックも入れています)。

03_スプライト1.png

そして、動かしたいキャラ(キャット)のコード内でそのメッセージ1を受け取り、それに対応する動作を発動させます。

04_動き1.png

こんな感じで左側のボタンも作れば、キャラを左右に動かすバーチャルボタンの出来上がりです。

以上になります。これで、電車の中でも思う存分ゲーム作りに励めますね!

実際にスマホで作ったプログラムはこちらから。
https://scratch.mit.edu/projects/311751784/

※この記事は、ここからの転載になります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Google I/O2019で発表されたGoogle Play、Google Play Consoleの追加された機能[WIP]

Google Play Store

pre-reg rewards

事前登録でリワードを追加。
例えばゲームで事前登録をすると何かアイテムをプレゼントなどが可能に。
事前登録は非常に効果が高いらしい。

アプリをDLせずともdemoの実行が可能に

アプリをDLしなくてもdemoアプリをストアから実行可能に

国ごとにアイコン設定が可能に

国ごとにアイコンを変更可能
セッションの例ではサッカーゲームのアイコンを国ごとに変更していた。

「ストアでの表示」 →「ストアのカスタム掲載情報」

ユーザーの状態ごとにアイコンを変更

以下のユーザーの状態でストア画像、動画を変更可能に(coming soon)
・未リリース
・インストール済み
・アンインストール

Google Play Consle

Developer-selected peer benchmarks

競合のアプリとアプリのベンチマークを比較可能に。

・Android Vitalsの「アプリのサイズ」から類似アプリとのアプリのダウンロードサイズの比較
・評価のレポートから類似アプリとの評価との比較

それぞれ、自動で作成されるが「類似アプリのグループ編集」から比較するアプリ集を変更可能

Play Coinsole metrics refresh

Suggested replies

Gmailなどにも使用されているように
レビューの返信に対して提案をしてくれる。

日本語では対応をしていないのか確認できず。

App download size breakdown

app bundleで上げているなら、アプリ内のどこにどれだけ容量を使っているかが分かるように。

session

What's New in Google Play (Google I/O'19)
https://www.youtube.com/watch?v=o_oUeciBknU&list=PLOU2XLYxmsILVTiOlMJdo7RQS55jYhsMi&index=87

Google Playのこと全体の話

Unleash the Power of Play Store Discovery (Google I/O’19)
https://www.youtube.com/watch?v=Nz_Ilg4BbKE

ゲームアプリ向けに新機能紹介。事前登録リワードや国別の設定変更に関してなど。非エンジニアにもおすすめ。

New Tools to Optimize Your App's Size and Boost Installs on Google Play (Google I/O’19) https://www.youtube.com/watch?v=rEuwVWpYBOY

アプリの容量が大事という話からApp Bundleに変えて最適化しようという話

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SimpleDateFormatでParseExceptionが出るときの確認点

Rssフィールドから日付を取得していたら、parseExceptionが出ました。

parseExceptionが起こった時の確認点をまとめたいと思います。

エラーは下記になります

java.lang.RuntimeException: An error occurred while executing doInBackground()
        at android.support.v4.content.ModernAsyncTask$3.done(ModernAsyncTask.java:161)
        at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
        at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
        at java.util.concurrent.FutureTask.run(FutureTask.java:271)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: java.text.ParseException: Unparseable date: "Fri, 24 May 2019 13:10:14 +0900"
        at java.text.DateFormat.parse(DateFormat.java:362)
    // (省略)

①形式はあっているか?

Rss.kt
val formatter = SimpleDateFormat("EEE, dd MM yyyy HH:mm:ss z")

最初に上記のように記載してしまいました。
リファレンスを見てみると、形式に誤りがあることがわかりました。

文字 説明 使用例
y yyyy = 2019
yy = 19
M MMMM = July
MMM= Jul
MM = 07
M = 7
H 時間 HH = 08
m mm=20
s ss= 58
z General タイムゾーン JST
Z RFC 822 タイムゾーン +0900
a AM/PM AM
k 1日の中での時間 13
K AM/PMの中での時間 01

上の表によると、MMという部分と、zの部分を間違っていました。
大文字・小文字で意味が全く違うものもあるので、要注意です。
下記の形式でパースできるはずです。

Rss.kt
val formatter = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z")

②環境依存はないか?

①だけだと不完全です。
パースしてみると下記が出力されます。

金, 24 5 2019 13:10:14 +0900

曜日が日本語表示になっていました。
デフォルトが日本語になっているようでした。
SimpledateFormatで形式を設定するときにロケールを設定する必要があります。

Rss.kt
val formatter = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US)

うまくパースできないときは上記のことを確認してみるといいかもしれません。

参照

Android Developers SimpleDateFormat
SimpleDateFormatクラスparseメソッドのLocaleに注意

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

10分でAndroidスマホにGo開発環境をたてる

Termuxのインストール

TermuxはAndroid用のターミナルエミュレータです。
Playストアにて「termux」を検索し、Termuxをインストールします。

Termuxを起動し以下のコマンドを実行します。

$ termux-setup-storage
$ apt update
$ apt upgrade

Go言語とgitのインストール

Termuxから、Goとgitをインストール。

$ apt install -y golang git

動作確認

Termuxにhello-worldアプリをgitクローンし、実行します。

$ git clone https://github.com/quzquz/go-http-hello-world.git
$ cd go-http-hello-world
$ go run main.go

少し待つと「Listening on port 8080」と表示されます。
Androidの適当なwebブラウザを起動しurlに以下を入力します。
http://localhost:8080

ブラウザに「Hello world!」と表示されます。

停止するには、Termux上でctrl+dを入力します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Kotlin】ボタンのタップ領域のみを拡張する

ボタンのサイズを変えずにタップ領域のみを拡張するという要件を実装していてハマったので備忘録として記事に残します。

コードだけ知りたいという方はこの記事の最後の方に載せていますのでそちらを確認してください。

タップ領域_expanded.png

どうやって実現するか

TouchDelegate を使って実装します。
公式リファレンスはこちら

上記の公式レファレンスで

Helper class to handle situations where you want a view to have a larger touch area than its actual view bounds.

と記載があるので今回の要件を実装する際の正攻法だと思います。
他にも良い方法がありましたらコメントで教えていただけると嬉しいです。

TouchDelegate

TouchDelegate を使って何をしているかというと
「タップ領域を拡張したいView(この例だとボタン)の祖先のViewに対して拡張したタップ領域(図のピンクの領域)を指定して、この領域内でタップイベントが発生した時の処理をタップ領域を拡張したいView(この例だとボタン)に委譲する」

ピンクの領域をタップした時の処理を、ボタンをタップした時の処理として扱う

ということをやっています。
ここでの注意点は、ピンクの領域を指定する祖先のViewにクリック処理を実装していた場合、ピンクの領域をタップしてボタンの処理が実行された後祖先のViewのクリックイベントが反応しなくなるという点です。

TouchDelegateを使ってみる

前置きが長くなりましたが実際に TouchDelegate を使ってみます。
ピンクの領域は祖先のViewに対して指定できるので、ボタンから見て階層が上のViewであれば利用できるのですが、個人的には親のViewに対して指定するのが良いかなと思います。
何故かというと、

ピンクの領域の座標をTouchDelegateを指定する祖先のViewからの相対座標で指定する必要があるからです。

注意点.png

※実際にタップ領域を拡張する時は ConstraintLayoutFrameLayout に対して指定する場面が多いと思うので親ViewGroupとしてますがViewでも大丈夫です。

コード

コードはこんな感じになります。

ViewEx.kt
func View.expandTapArea() {

    val parentViewGroup = this.parent as ViewGroup
    parentViewGroup?.post {

        val rect = Rect() // <- ピンク領域のRect

        // ピンク領域のRectを生成

        parentViewGroup.touchDelegate = TouchDelegate(rect, this)
    }
}

// 使い方
button.expandTapArea()

以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

配布済アンドロイドアプリのインストールを、特定国、特定機種でブロックする ~ 先日のHUAWEI騒動を受けて ~

今回の HUAWEI 騒動を受け、個人的に米国とGoogleの対応にはかなりむかついたので、自分が公開しているandroidアプリ「media.Re.Scan」の配布対象から、google製端末(nexus, pixel, chromebook系デバイス)と、 アメリカ合衆国(全土)を除外することにしました((Googleの方は、「本国の指示に従え」との上からのお達しに準じただけ、というのは、まあ一応想像はつくのですが))。

ちなみに、「media.Re.Scan」は、初版を2014年頃に公開したアプリで、累積インストール数は100万~500万ユーザ、ただし過去30日のアクティブユーザは記事執筆時点では7万程度です。

今回は、公開済みのandroidアプリの配布に、特定の地域、特定機種からのインストール、アップデートを拒否する方法 を書いていきます。

なお、インストール、アップデート制限機能のまっとうな利用用途としては、例えば以下のようなケースが想定されると思います。

  • 特定機種だけアプリが正常に動作しない&修正もできない(あるいは、めんどくさい、よくわからん、等)ため、その機種の端末からはインストールできないようにしたい、
  • 法律や権利の問題により、特定の国ではアプリを利用できないようにしたい。

これらの設定は、Google Play Console から行います。

まずは、アプリを公開したユーザとして、Google Play Console にログインしてください。
設定は、アプリごとの設定となるため、[すべてのアプリ]画面から設定をしたいアプリを選択し、アプリのダッシュボード画面を表示させてください。

特定機種からのインストール、アップデートをブロック

device.png

特定機種からのインストールをブロックする設定は、[リリース管理] - [デバイスカタログ] にあります。
この画面では、対応機種数の確認、機種ごとのアクティブユーザ数や平均評価値などの確認ができたり、特定の機種からのインストールを無効にすることもできるようになっています。

デフォルトっ表示では、端末の外観イラストがタイル状に表示されるモードになっているのですが、これがとても見ずらい&操作しずらいです。
そのため、まずは表示方式をリスト表示モードに変更することをお薦めいたします(画面中央右端のイメージボタン)。

画面上部の検索窓で、機種名、端末メーカー名などで、検索できるようになっているので、目的の機種を探します(Google、HUAWEI、Xperia など)。

画面下半分に表示される見つかった機種一覧から、インストール、今後のバージョンのアップデートを無効にしたい機種を選択します。

保存ボタン(リストの上、画面中央右端)を押すと、この変更により、影響を受けるアクティブインストール端末数、平均評価が表示されるので、確認後に設定を確定します。

なお、この変更を行ったとしても、既にインストール済の端末には影響はないようです。
ただし、新バージョンを配布したとしても、ユーザは更新することもできなくなります。

特定の国からのインストール、アップデートをブロック

kuni_1.png

特定の国からのインストール、アップデートをブロックする設定は [ステアでの表示] - [価格と配布] の中にあります。

画面を開いて、「国* 」アイテム横の「国を管理」ボタンを押すと、配布を許可する国、許可しない国設定画面が表示されます。

kuni_2.png

配布したくない国を選んで、使用不可にチェック入れ、設定が完了したら、画面一番下の「アップデートを送信」ボタンを押します。
「アップデートを処理しています」というメッセージが表示され、設定が適用されます(適用までに数時間かかるようです)。

なお、いくつかの国については、携帯通信会社ごとに設定を変えることもできます。
日本の場合には、「ドコモ」「ソフトバンク」「au」「Y!mobile」が選択できるようになっています。
2019年10月から独自通信網によるサービスを開始する楽天モバイルも、サービス開始後に設定可能になると思います。
また、MVNO会社がどのような扱いになっているのかは不明です(おそらく、親元の回線事業者の設定を引き継いでいるのかとは思いますが未確認です)。

設定を行う場所が、2つのケースでばらばらで、個別機種の対応は「デバイスカタログ」というメニューから変更する必要があり、少しわかりづらい印象でした。

何はともあれ、これで、国ごと、機種ごとのインストール可否を細かく制御することができるようになり、無用なトラブルも未然に防ぐことができるようになります。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Nexus5にAndroid9をいれました

まえがき

Android6 以降アップデートが来ない見放された名機 Nexus5 に、最新の Android9 を入れました。2014後半発売で、いまとなっては寂しいスペック(MSM8974 2.26GHzQuadCore/2GM RAM)ですが、あほみたいな安値で投げ売られてるし、ちょっと遊ぶ用途には最高でした。

成果物

image.png

必要資材

作業手順

必要なSDK、解凍ソフトをインストール(AndroidStudio入れなくてもいけます)

console
$ brew cask install android-sdk
$ brew cask install android-platform-tools # このバージョンでは相性問題が出ましたが、後述
export ANDROID_HOME=“/usr/local/share/android-sdk”
export PATH=${PATH}:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools”
$ brew install unrar

ダウンロードしたものを確認

console
$ ls -la
-rw-r--r--@  1 saitotak  staff   1557161890  5 25 16:26 FirstEver-Android-9.0-hammerhead-20181214.rar
-rw-r--r--@  1 saitotak  staff     13608960  5 25 16:26 twrp-3.3.1-0-hammerheadcaf.img

Android側はUSBデバッグを有効にしてUSB接続し、ブートローダー起動

console
$ adb devices
$ adb reboot bootloader

カスタムリカバリを書き込んで再起動

console
$ fastboot flash recovery twrp-3.3.1-0-hammerheadcaf.img
target reported max download size of 1073741824 bytes
sending 'recovery' (13290 KB)...
OKAY [  0.616s]
writing 'recovery'...
OKAY [  1.048s]
finished. total time: 1.665s

$ fastboot reboot
rebooting...

finished. total time: 0.100s

リカバリモードでTWRPを起動して、一応バックアップ取得、
取得したパスが出てくるので、デスクトップにイメージをコピーしておく

console
$ adb pull /data/media/0/TWRP/BACKUPS/014dbbbc037b6f59 /Users/saitotak
/Desktop

014dbbbc037b6f59 という数字がなんなのかよくわからず、環境によって変わるかも

イメージ解凍してAndroidへpush

console
$ unrar x FirstEver-Android-9.0-hammerhead-20181214.rar ./FirstEver-Android-9.0-hammerhead-20181214
$ adb push /Users/saitotak/Downloads/FirstEver-Android-9.0-hammerhead-20181214 /data/media/0/TWRP/BACKUPS/014dbbbc037b6f59

で、再起動したら無事起動しました。

その他参考情報

MacOS と fastboot(android-platform-tools) の相性で fastboot 実行時に下記のエラーが出る場合、android-platform-tools 26.0.1 にダウングレードすると解消しました

ERROR: Couldn't create a device interface iterator: (e00002bd)
ERROR: Couldn't create a device interface iterator: (e00002bd)

mac os x - "Fastboot devices" command doesn't work after macos high sierra 10.14.4 upgrade - Android Enthusiasts Stack Exchange

adb shell でシェルログインできるべんり

console
# adb devices 
List of devices attached
014dbbbc037b6f59        recovery

# adb shell
~# pwd
/

参考にしたリンク

Nexus5 Android9 のセットアップ - Radi開別館
First Ever Android 9.0 for Nexus 5 | First Ever
adbコマンドを使ってファイルを端末に転送する - Qiita
[Mac]sbtの特定のバージョンをbrew installでインストールする方法 - Qiita
Nexus 5|過去の製品|製品|Y!mobile - 格安SIM・スマホはワイモバイルで

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

飯田橋系こそFlutterを使うべき5つの理由

フロントエンド開発のマルチプラットフォームとしてGoogleが推しているFlutterは、渋谷系の人々からも熱い注目を浴びていますが、飯田橋系1の人々こそ使うべきだと考えます。その理由を述べたいと思います。

なお渋谷系としてもFlutterを使う理由は多く、「Flutterとは? エヌ次元が企業としてFlutter開発を採用する理由」が参考になります。(渋谷にオフィスを持つ典型的な渋谷系企業ですね・・)

1. モバイルファーストなマルチプラットフォーム

2000年代からWebシステムの常識であったMVCモデルは、非同期かつ複雑なWebシステムをViewとModel(ビジネスロジック)とに分離して、開発保守効率を上げることが目的でした。この方面で成功したフレームワークが、StrutsやSpringです。対象がPCだけでなくスマホやタブレットと増えてきても、画面サイズのバリエーションが増えたものと位置づけて、PC向けWeb画面をマルチウインドウを考慮したレスポンシブデサインにする、というやり方で対応できました。そのため、ネイティブアプリとは生態系が分かれていました。

2016〜7年から、Webにモバイルファーストの潮流がやってきました。まずスマホ向けにインタラクティブに溢れたページをデサインし、それを横に並べた形でPC向けを作ります。Webの作り方も、従来のサーバーサイドレンダリングから、クライアント側でインタラクティブにレンダリングをする「SPA」が主流になり、ロジックの多くがクライアントサイドのUI向けに実行されるようになり、ネイティブアプリとの親和性も高くなりました。モバイルを、画面サイズのバリエーションではなく、一種のエッジコンピューティングと位置づけたことになります。また、Webバックエンド開発は、さまざまなPaaSやそれらを組み合わせたマイクロサービスアーキテクチャーが主流になり、ビジネスロジックの軽量化が進みました。

このような中で台頭したのが、SPAに特化しつつ、Viewを、VM(View Model)とViewに分離することで新たな複雑性に対応しようとする、MVVMモデルです。Viewが複雑になり、デザイナーが一人でHTML/CSSを書きつつちょこっとJavaScriptを書いていた時代は過ぎ去りました。MVVMモデルは、Viewをデサイナー(View)とデベロッパー(View Model)で分担して作ることを容易にします。MVVMを実現するフレームワークとして、Angular、Vue、Xamarinなどが台頭しました。さらにMVVMよりもViewの複雑性に対応したのが、"Just the UI"を標榜したReact、さらにBLoCモデルを加えたReact/Reduxであり、React(/Redux)をネイティブアプリ2まで対応できるようにしたのがReact Nativeです。これら(総称してReactと呼びます)が、現時点の渋谷系一番人気のフレームワークになっています。

このあたりの議論がよく理解できない人は、「Flutterのアーキを図1枚で説明してみる」を参考にしてください。

Flutterは、そのReactにインスパイアされてGoogleが提供したフレームワークであり、Webからネイティブアプリまでのマルチプラットフォーム対応3のフロントエンド開発フレームワークとなっています。

2. Java開発者が移行しやすいDart2

動的型定義でさくさく書けるJavaScriptは、渋谷系人気の言語です。Angular、Vue、ReactはいずれもJavaScriptを基軸4とするフレームワークであり、渋谷系の人気を博しました。Node.jsとかNode-REDが流行るのもこの流れです。

一方、きっちりとした開発を好む飯田橋系はJavaが大好きで、これらのJavaScript系フレームワークを、実証実験ではなく商用システムとして利用することには抵抗感があります。

Dartは、Dart1ではJavaScript的な動的型定義の言語であったのですが、Flutterとともに出したDart2において、実質的に静的型定義の言語に大幅リニューアルをしました。位置づけ的に「Better Java」(しかしScalaほどは跳躍しない)となり、Javaの古びたところを改善して開発効率を高めたものとして、Java開発者に受け入られやすいものになりました。

3. 安心のGoogleブランド

元来、飯田橋系はオープンソースに対して保守的であり、「保証のないものを使うのはいかがなものか」という文化でした。そうはいっても時代の流れには逆らえずオープンソースを使うわけですが、もとの文化の影響で、強い企業がしっかりとバックアップしているオープンソースを好む傾向にあります。その点で、FlutterはGoogleが強くコミットしており、万全です。

ReactにコミットするFacebookも負けず劣らず強力ではあります。しかし、FacebookはSNSを主事業としているため、同じプラットフォーム技術を長く提供しつづけるインセンティブは相対的に弱いです。実際、過去にCassandraという素晴らしいプロダクトをオープンソースに出しましたが、現時点のFacebookではあまり使われていない模様です。一方、Googleは、以前はプラットフォーム技術に関してはやや閉鎖的な印象があり、外部に最新のノウハウは出さない企業文化でした。しかし、ここ最近は様変わりをして、オープンソースコミュニティと積極連携し、Kubernetesをはじめとした素晴らしいプロダクトを提供しはじめました。GCPを、AWSやAzureに対しての競合として成長させようとしており、先行2社に対して競争力あるポジショニングをとろうとしているためと思われます。

現時点で、コミュニティ全体はReactの方が優勢ですが、FlutterはGoogleが精力的にコミットしているため公式のWidgetやドキュメントが手厚い状況です。渋谷系は自分自身がコミュニティに積極関与するためReactでも問題ありませんが、そこまでではない飯田橋系には「公式が強い」という方が魅力です。オープンソースって何なの?という根源的な問いが生まれてしまう悩ましい話ですが、そうなのです。

4. Reactに乗り遅れたからこそFlutter

2013年からの歴史があるReactは、項1で述べた潮流をつかんだ渋谷系を席巻しました。そのため、渋谷系ではReactの開発者や開発ノウハウがそれなりに蓄積されています。そのため、渋谷系がFlutterに移行するインセンティブはあまり高くありません。

しかし、Reactには無縁であった飯田橋系は事情が違います。これまでの蓄積がありませんので、Flutter or Reactで悩む必要はありません。SPAやネイティブアプリにそろそろ本腰を入れよう、と決断したら、選択肢はFlutterのみになります。むしろ、積極的にFlutterを使うことで、いわゆるリープフロッグ現象(途上国が最新技術により急激に発展する現象)により、一足飛びにフロントエンド開発の競争力がつくことが期待されます。

なお、「SPAやネイティブアプリなんて必要無い! 5Gになれば高速低遅延になって今までのサーバーサイドレンダリングのWebアプリで十分! Struts/Spring万歳!」などと考えているとしたら、それはファンタジーですので、「LTE→5Gはブレークスルーにはならない」を読んで考えを改めてください。

5. 若手技術者の雇用問題も解決

飯田橋系にとって深刻な問題は、若手の優秀な技術者の雇用維持です。若手の優秀な技術者は、新卒/中途ともに、渋谷系に流れていってしまっています。技術に自信と実績のある人ほど、今更COBOLの保守開発とか、技術者とは名ばかりの調整役というプロマネとか、やりたくありません。

Flutterに注力することで、そのような問題は解消できます。なにしろ渋谷系の傾倒するReactよりも新しいフレームワークです。最新フレームワークでバリバリと開発できることをアピールすることで、飯田橋系にも優秀な技術者が集まるでしょう。


  1. ベンチャー企業の代名詞である「渋谷系」に対して、お固い企業向けシステムに携わるエンジニアを、某通信事業者の社内拠点とそのカルチャーの違いになぞらえて「飯田橋系」と呼ぶそうです。 

  2. 文脈上、ネイティブアプリとクロスプラットフォームを、用語として区別していません。 

  3. 現時点でWeb向けはプレビュー版です。 

  4. TypeScriptという静的型定義に近い派生はありますが、ここではフレームワークの根源的な文化に焦点をあてていますので、これもJavaScriptの仲間とします。 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Android Pie対応するときにTextViewの改行の行間でハマった話

targetSdkVersionを28にした

Android 9 へのアプリの移行 を読んで
compileSdkVersionとtargetSdkVersionを28に変更してビルド実行、ビルド通ったし動作確認するかー
と動作確認していたときに「android:lineSpacingMultiplier」を設定している箇所を開いた際に
アレ?行間広くなってね?
と思って調べたときにハマったので記載

問題の表示

実際の表示を確認するためにTextViewのHello Worldを改行付き文字に置き換えただけの
Empty Activityで作成したプロジェクトを用意し検証

Android 8のEmulator Android 9のEmulator

TextViewの内容

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="君がッ\n泣くまで\n殴るのを\nやめないッ!"
    android:lineSpacingMultiplier="1.5"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

明らかに行間が開いている!

不具合では?思って調査してみると…

調査してみるとgoogle issue trackerに似たような話が…
どうやら不具合ではなく想定通りの動作らしく
fallbackLineSpacingをfalseにすれば戻ると言う事なので実際に試してみる

google issue tracker
https://issuetracker.google.com/issues/122554779

※Android DevelopersのfallbackLineSpacingの記載箇所
https://developer.android.com/reference/android/widget/TextView.html#attr_android:fallbackLineSpacing

実際に試してみた結果

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="君がッ\n泣くまで\n殴るのを\nやめないッ!"
    android:lineSpacingMultiplier="1.5"
    android:fallbackLineSpacing="false"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />
Android 8のEmulator Android 9のEmulator

android:fallbackLineSpacingにfalseを設定すると行間が同じになった!

関係ありそうな箇所を見てみる

fallbackLineSpacingの箇所をみてみるとこのようなコードになっていたので
PieからデフォルトがfallbackLineSpacingがtrueになる様子

mUseFallbackLineSpacing = context.getApplicationInfo().targetSdkVersion >= VERSION_CODES.P;

fallbackLineSpacingの説明をGoogle先生の翻訳にかけてみると下記の内容になるのでtrueが設定されている場合には行間が増えてしまうっぽい?

翻訳後の内容
「テキストの表示に使用される代替フォントの上昇および下降を尊重するかどうか。trueの場合、使用されてしまうフォールバックフォントは、使用されている行の上昇および下降を増やす可能性があります。」

Android 9 へのアプリの移行を読んだけど…

今回この事象にぶつかってからどうしたら解決できるのか情報を漁り、この方法を発見したが見つけるまで苦労した…
この辺りの事は特に記載が無い気がする(見逃しているだけ? or 自分が無知なだけ?)
android:fallbackLineSpacingにfalseを設定すれば行間を合わせられそうだが…他の方法とかあるんだろうか…

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

既存のC/C++コードをAndroidアプリケーションに組み込む

この記事について

既存のC/C++コードを、Android NDKを用いて、ネイティブ関数としてAndroidアプリケーションに組み込みます。
基本的には、公式のUSER GUIDE(https://developer.android.com/studio/projects/add-native-code )のまんまです。

想定するシチュエーション

  • 元々、CMakeを使って、C/C++アプリケーション開発をしていた
    • 普段の開発環境はVisual Studioとか、GCC
  • アプリケーションをAndroidに移植する必要が出てきた
    • 移植するのは、コアとなるライブラリ部のみ(関数)
    • アプリケーション部(main関数や描画処理)は移植しない。アプリケーション部に該当するのはJava側で作られるはず
  • 「移植」とはいえ、ライブラリ部は従来のC/C++アプリケーションでも使うし、新規に開発するAndroidアプリケーションでも使う。二重メンテはしたくないので、共用したい

既存のプロジェクト

以下のような非常にシンプルなプロジェクトを考えます。
Main.cpp にはmain関数のみがあります。普段のC/C++開発ではこのmain関数が「アプリケーション」として主に動いているとします。今回、Android側では使用しません。
Submodule には関数群があります。今回は、単に入力値を2倍するだけのSubModule_funcDouble という関数を用意しました。これを「ライブラリ」としてJavaから呼ぶことを今回の目標にします。

プロジェクト構造
MyProject
├─CMakeLists.txt
├─Main.cpp
└─SubModule
   ├─CMakeLists.txt
   ├─SubModule.cpp
   └─SubModule.h
TopのCMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project("C_application") 

add_executable(Main "Main.cpp")

add_subdirectory(SubModule)
target_include_directories(Main PUBLIC ./SubModule)
target_link_libraries(Main SubModule)
Main.cpp
#include <stdio.h>
#include "SubModule.h"

int main()
{
    SubModule_funcDouble(10);
    return 0;
}
SubModuleのCMakeLists.txt
cmake_minimum_required(VERSION 3.0)
add_library(SubModule STATIC SubModule.cpp SubModule.h)
SubModule.cpp
#include <stdio.h>
#include "SubModule.h"

int SubModule_funcDouble(int a)
{
    printf("SubModule_funcDouble: %d x 2 = %d\n", a, a * 2);
    return a * 2;
}
SubModule.h
#ifndef _SUB_MODULE_H_
#define _SUB_MODULE_H_

#ifdef __cplusplus
extern "C" {
#endif
#if 0
}
#endif

int SubModule_funcDouble(int a);

#ifdef __cplusplus
}
#endif

#endif  /* _SUB_MODULE_H_ */

Androidアプリケーションを作る

NDKのインストール

まず、Android Studioの適当なプロジェクトを開き、メニューバー -> Tools -> SDK Manager を開きます。
SDK Toolsから、LLDBCMakeNDK を選びOKをクリックしてインストールします。

01.png

(これは、後でプロジェクトを作ってからやっても良いです)

Androidプロジェクトの生成

Android Studioを開き、新規プロジェクトを作ります。
テンプレートを選ぶ際に、Native C++ を選びます。

03.png

プロジェクトの保存場所

僕は、C/C++と一緒にソースコード管理したかったので、以下のように同じ場所にAndroidApp というフォルダを作り、その中に保存しました。

プロジェクト構造
MyProject
├─AndroidApp/     <-- ここにAndroidプロジェクトを保存
├─CMakeLists.txt
├─Main.cpp
└─SubModule/
   ├─CMakeLists.txt
   ├─SubModule.cpp
   └─SubModule.h

メモ: 他の方法

C/C++コードとAndroid用コードを別々に管理する場合には、全然別の場所に保存しても大丈夫です。
また、C/C++コードも新規に作る場合には、Androidプロジェクトの中にCPPフォルダがあるのでそこに保存していけばいいと思います。おそらくこれが想定された使い方だと思います。
ただ、今回は「既存の」C/C++コードを使いたいということと、C/C++コードをAndroidとは関係なく既存のC/C++プロジェクトとして使用している人もいることを想定して、上記のような構成にしました。(共通のライブラリ関数を、Androidアプリでも使うし、C/C++プロジェクトでも使う場合を想定)

どういう構成で各種ファイルを保存するかは、プロジェクト体制やチームメンバー、運用方法によって決めてください。

メモ: 既存のAndroidプロジェクトにC/C++を組込む場合

取り込みたいプロジェクト(app) を右クリックして、Link C++ Project with Gradle を選べば大丈夫です。ただ、後で紹介するようなCMakeLists.txtのひな形などは作られないようです。

02.png

C/C++コードの編集

05.png

生成されたプロジェクトを見ると、上記のようにcpp というフォルダが作られ、その下にCMakeLists.txtnative-lib.cpp が作られています。デフォルトで、Hello Worldという文字列を返すだけの関数を用意したライブラリのひな形が作られています。

以後、CMakeLists.txtを変更した場合は、まずはメニューバー -> Build -> Reflesh Linked C++ Projects をするといいと思います。

CMakeListsの編集

C/C++コードも新規で作る場合にはこのCMakeListsもがりがり編集して良いと思うのですが、今回は既存のC/C++コードを取り込むだけなので、出来るだけ変更の手間が少なくなるようにします。

以下のように、既存のC/C++コードのSubModuleのadd_subdirectory と、インクルードパスの追加、リンク設定だけを最後に追加しています。パスの指定は、このCMakeLists.txt からの相対パスになります。
今後SubModuleの方でファイルを増やしたり、さらに別のモジュールを呼んだりしても、ここを変更する必要はなくなります。(依存性を駄々洩れにしたヘッダファイルを作ったりしなければ、ですが)

native-lib/CMakeLists.txt
~略~

add_library( # Sets the name of the library.
        native-lib

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        native-lib.cpp)

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

~略~

target_link_libraries( # Specifies the target library.
        native-lib

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

# ↓追加
add_subdirectory(../../../../../SubModule SubModule)
target_include_directories(native-lib PUBLIC ../../../../../SubModule)
target_link_libraries(native-lib SubModule)
# ↑追加

native-lib.cppの編集

元々用意されている、Hello worldという文字列を返すだけの関数があります。
別にこれは名前を変えてもいいのですが、そのまま使います。

今回呼びたい関数はSubModule の中にあるので、基本的にはここにはWrapperとしての役割を担ってもらいます。
JNIに則って、JavaとC/C++のインターフェイス変換をしてもらいます。また、今回はintだけなので簡単ですが、配列やオブジェクトが引数や戻り値にある場合には、その変換もしてもらいます。

native-lib.cpp
#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_myapplication_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

// ↓追加
#include "SubModule.h"
extern "C" JNIEXPORT jint JNICALL
Java_com_example_myapplication_MainActivity_funcDouble(
        JNIEnv *env,
        jobject /* this */,
        jint a
) {
    int ret = SubModule_funcDouble(a);
    return ret;
}
// ↑追加

JavaコードからC/C++関数を呼ぶ

いよいよ、JavaコードからC/C++関数を呼んでみます。
ライブラリ(so)ファイルのロード処理(loadLibrary )は既に自動生成されています。

C/C++ネイティブ関数の宣言をします。どうも一番下に書くのがお作法みたいです。
その後、関数コールは普通のJavaコードとして実装できます。

MainActivity.java
package com.example.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(stringFromJNI());

        // ↓追加
        int ret = funcDouble(10);
        Log.i("MyApp", "funcDouble: " + ret);
        // ↑追加
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public native String stringFromJNI();

    // ↓追加
    public native int funcDouble(int a);
    // ↑追加
}

メモ

printf

C/C++側でのprintfはどこにも出力されず、無視されるみたいでした。ただ、おそらく環境依存なので、#ifdef __ANDRDOID__ などでprintfにするか__android_log_print にするかを切り替えられるようにした方がよさそうです

fopen

万が一、C/C++側でファイル読み書きするコードがある場合、何の考慮もしないとSIGSEGVでクラッシュします。
ファイル読み書きに対応するには、

  • Manifestに、<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> を追加
    • その後、Androidのアプリ設定から権限付与。または、本記事のようにアプリから自発的に権限付与を催促する
  • fopenで指定するパスをAndroidシステム上で存在するディレクトリにする
    • カレントディレクトリに出力したいからと、fopen("test.txt", "w"); とするのはダメ
    • 例えばシステムメモリのトップに出力するためには、fopen("/sdcard/test.txt", "w"); とする

OpenMP

native-lib下のCMakeLists.txt に以下を追加することで、普通に使えました。
SubModule下のCMakeLists.txtにつけるのだと、上手くいきませんでした。(ビルドエラー発生)

native-lib下のCMakeLists.txtに以下を追加
# ↓追加
find_package(OpenMP REQUIRED)
if(OpenMP_FOUND)
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
# ↑追加

add_subdirectory(../../../../../SubModule SubModule)
target_include_directories(native-lib PUBLIC ../../../../../SubModule)
target_link_libraries(native-lib SubModule)

また、UIスレッドからの呼び出しじゃないとCrashするという情報がネットにありましたが、UIスレッド以外からの呼び出しでも問題なく動いているようです。(NDKバージョンは19.2)
具体的には、OpenCVのCameraBridgeViewBase.CvCameraViewListeneronCameraFrame コールバック内でネイティブ関数を呼び、その中でOpenMPでfor文を回してみましたが、クラッシュなく動作していました。高速化もされていました。

おわりに

かなり的を絞ったユースケースを想定した方法です。
もっといい方法があるかもしれません。
改善点があれば、コメントなどで教えていただけると嬉しいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

最近(2019/05)のAndroid開発でよく使われているっぽいライブラリまとめ

私は去年から真面目にAndroid開発を始めたのですが、プロダクトの開発で息するように使われているライブラリなどは誰も教えてくれず知るまでなかなか時間がかかりました。この記事ではこれからAndroid開発を始める人向けに今よく使われているライブラリをまとめます。

「よく使われている」は完全に主観です。

AAC

Android Architecture Componentsの略で、Android Jetpackのコンポーネントの一つです

https://developer.android.com/jetpack?hl=JA

AACに含まれるライブラリの中でも特によく使うものについて紹介します。

Data Binding Library

https://developer.android.com/topic/libraries/data-binding/?hl=JA

文字通りデータバインディングに使うライブラリです。私はMVVMでの開発でよく使ってます。XMLにオブジェクトをバインドしたり、後述するLiveDataなどで双方向のデータバインディングもできるので大変便利です。

Lifecycle

https://developer.android.com/topic/libraries/architecture/lifecycle?hl=JA

ActivityやFragmentのライフサイクルを管理します。LifecycleObserverを使うとActivityやFragmentのライフサイクルイベントを他のクラスで監視することができるのでとても便利です。

LiveData

https://developer.android.com/topic/libraries/architecture/livedata?hl=JA

LiveDataはライフサイクルと連動して、値の変更を通知することができます。私はRxのSubjectを使ってレイヤー間の通知を行っていた部分をLiveDataに置き換えました。双方向のデータバインディングにも利用できて便利です。

Room

https://developer.android.com/topic/libraries/architecture/room?hl=JA

RoomではSQLiteをスムーズに使えるようなインターフェースを提供しています。私はそこまでがっつり使ってないのでなんとも言えません。

ViewModel

https://developer.android.com/topic/libraries/architecture/viewmodel?hl=JA

ViewModelはActivityやFragmentのライフサイクルと関連づけてUI関連のデータを管理することができます。いわゆるMVVMのViewModelとは文脈が少々異なる物だと思いますが、MVVMでのアプリケーション開発にはとても役立ちます。私はめちゃくちゃ使っています。

その他

  • WorkManager
    • ぶっちゃけ使ったことないので知りません
  • Navigation
    • 遷移周りを管理します。safeArgs(Fragment間でのデータ受け渡しに使えるモノ)が便利だった
  • Paging
    • ぶっちゃけ使ったことないので知りません

通信周り

okhttp + retrofit + RxJava(RxKotlin) + RxAndroid + moshi(gson) みたいな構成をよく見ます。 最近はcoroutineを使った非同期処理もよく見かけます。

HTTPクライアント

okhttp

https://github.com/square/okhttp

デファクトでしょう。私はこれが無いと生きていけないです。

retrofit2

https://github.com/square/retrofit

RESTをいい感じに扱えるライブラリ。okhttpと一緒に使うことが多し。

JSONパーサ

一昔前はJacksonが使われていたらしい?

gson

https://github.com/google/gson

google製です。よく見ます。私はDeserializerを自分で書かなきゃいけない時など複雑な要件の時に使ってます。

moshi

https://github.com/square/moshi

square製です。最近は専らこっちを使ってます。

kotshi

https://github.com/ansman/kotshi

kotlin実装です。kotlin向けのMoshiのadapter。

画像

glide

https://github.com/bumptech/glide

画像表示には欠かせない存在です。よく見ます。

picasso

https://github.com/square/picasso

こっちもよく見ます。体感的にはglideの方が使われてそう。

Rx

RxJava

https://github.com/ReactiveX/RxJava

リアクティブプログラミングというパラダイムのコード記述ができます。学習コストは高いですが覚えると大変便利です。非同期処理用のライブラリだと思われがち。最近は他の技術に置き換える流れを感じますがまだまだ色んなところで使われているし個人的にはこれが無いとかなり辛い。

RxKotlin

https://github.com/ReactiveX/RxKotlin

RxJavaのKotlin拡張です。KotlinでRxを使うならぜひ導入しましょう。

RxAndroid

https://github.com/ReactiveX/RxAndroid

Android開発におけるRxJavaでの非同期通信には欠かせない存在です。

RecyclerView

groupie

https://github.com/lisawray/groupie

最近人気すぎて怖い。でも確かに便利です。

epoxy

https://github.com/airbnb/epoxy

airbnb製。ぶっちゃけ使ったこと無いのでよくわかりませんが便利そう。MvRxや他のairbnb製のライブラリと相性が良さげです。

デバッグ関連

Log代替

timber

https://github.com/JakeWharton/timber

android.util.Logのラッパーです。誰も教えてくれないけどみんな使ってます(主観)。ビルドタイプによる機能の切り替えなどができます。

メモリ管理

leakcanary

https://github.com/square/leakcanary

信頼と実績のsquare製。アプリのメモリリークを検出し、通知します。当たり前のように使われている感じがします。

通信ログ周り

stetho

https://github.com/facebook/stetho

okhttpに噛ませるとChromeで通信ログなどが見れます。めちゃ便利。

flipper

https://github.com/facebook/flipper

Facebook製。Android以外のプラットフォームでも使えます。使ってる人見たことないです。stethoで良くね?

その他

Hyperion-Android

https://github.com/willowtreeapps/Hyperion-Android

色々できます。詳しくはこちらの記事を見てください。

DI

Dependency Injectionの略です。最近は知ってて当たり前感があります。参考

dagger2

https://github.com/google/dagger

square発google製。めちゃくちゃ使われてます。学習コストはかなり高いと思います。

koin

https://github.com/InsertKoinIO/koin

kotlin実装のDIライブラリ。知名度も上がってきて勢いを感じます。daggerよりわかりやすいので私は好きです。

テスト周り

mockito

https://github.com/mockito/mockito

モッキングフレームワークです。デファクト感があります。

mockk

https://github.com/mockk/mockk

kotlin実装のモッキングライブラリです。最近見かけるようになりました。

その他

ThreeTenABP

https://github.com/JakeWharton/ThreeTenABP

Androidで日付を簡単に扱えるライブラリ。誰も教えてくれないけど大変便利で使ってる人も多いはず。

所感

  • Java -> Kotlinの流れを強く感じます(koinとか)
  • 最近のAndroid開発ではdaggerやRxなど学習コストの高いものを覚える必要があり、開発を始める敷居が高くなっているように思います
  • 「これはみんな使ってるっしょ!」みたいなライブラリがあれば是非教えてください
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

最近のAndroid開発でよく使われているっぽいライブラリまとめ(2019/05)

私は去年から真面目にAndroid開発を始めたのですが、プロダクトの開発で息するように使われているライブラリなどは誰も教えてくれず知るまでなかなか時間がかかりました。この記事ではこれからAndroid開発を始める人向けに今よく使われているライブラリをまとめます。

「よく使われている」は完全に主観です。

AAC

Android Architecture Componentsの略で、Android Jetpackのコンポーネントの一つです

https://developer.android.com/jetpack?hl=JA

AACに含まれるライブラリの中でも特によく使うものについて紹介します。

Data Binding Library

https://developer.android.com/topic/libraries/data-binding/?hl=JA

文字通りデータバインディングに使うライブラリです。私はMVVMでの開発でよく使ってます。XMLにオブジェクトをバインドしたり、後述するLiveDataなどで双方向のデータバインディングもできるので大変便利です。

Lifecycle

https://developer.android.com/topic/libraries/architecture/lifecycle?hl=JA

ActivityやFragmentのライフサイクルを管理します。LifecycleObserverを使うとActivityやFragmentのライフサイクルイベントを他のクラスで監視することができるのでとても便利です。

LiveData

https://developer.android.com/topic/libraries/architecture/livedata?hl=JA

LiveDataはライフサイクルと連動して、値の変更を通知することができます。私はRxのSubjectを使ってレイヤー間の通知を行っていた部分をLiveDataに置き換えました。双方向のデータバインディングにも利用できて便利です。

Room

https://developer.android.com/topic/libraries/architecture/room?hl=JA

RoomではSQLiteをスムーズに使えるようなインターフェースを提供しています。私はそこまでがっつり使ってないのでなんとも言えません。

ViewModel

https://developer.android.com/topic/libraries/architecture/viewmodel?hl=JA

ViewModelはActivityやFragmentのライフサイクルと関連づけてUI関連のデータを管理することができます。いわゆるMVVMのViewModelとは文脈が少々異なる物だと思いますが、MVVMでのアプリケーション開発にはとても役立ちます。私はめちゃくちゃ使っています。

その他

  • WorkManager
    • ぶっちゃけ使ったことないので知りません
  • Navigation
    • 遷移周りを管理します。safeArgs(Fragment間でのデータ受け渡しに使えるモノ)が便利だった
  • Paging
    • ぶっちゃけ使ったことないので知りません

通信周り

okhttp + retrofit + RxJava(RxKotlin) + RxAndroid + moshi(gson) みたいな構成をよく見ます。 最近はcoroutineを使った非同期処理もよく見かけます。

HTTPクライアント

okhttp

https://github.com/square/okhttp

デファクトでしょう。私はこれが無いと生きていけないです。

retrofit2

https://github.com/square/retrofit

RESTをいい感じに扱えるライブラリ。okhttpと一緒に使うことが多し。

JSONパーサ

一昔前はJacksonが使われていたらしい?

gson

https://github.com/google/gson

google製です。よく見ます。私はDeserializerを自分で書かなきゃいけない時など複雑な要件の時に使ってます。

moshi

https://github.com/square/moshi

square製です。最近は専らこっちを使ってます。

kotshi

https://github.com/ansman/kotshi

kotlin実装です。kotlin向けのMoshiのadapter。

画像

glide

https://github.com/bumptech/glide

画像表示には欠かせない存在です。よく見ます。

picasso

https://github.com/square/picasso

こっちもよく見ます。体感的にはglideの方が使われてそう。

Rx

RxJava

https://github.com/ReactiveX/RxJava

リアクティブプログラミングというパラダイムのコード記述ができます。学習コストは高いですが覚えると大変便利です。非同期処理用のライブラリだと思われがち。最近は他の技術に置き換える流れを感じますがまだまだ色んなところで使われているし個人的にはこれが無いとかなり辛い。

RxKotlin

https://github.com/ReactiveX/RxKotlin

RxJavaのKotlin拡張です。KotlinでRxを使うならぜひ導入しましょう。

RxAndroid

https://github.com/ReactiveX/RxAndroid

Android開発におけるRxJavaでの非同期通信には欠かせない存在です。

RecyclerView

groupie

https://github.com/lisawray/groupie

最近人気すぎて怖い。でも確かに便利です。

epoxy

https://github.com/airbnb/epoxy

airbnb製。ぶっちゃけ使ったこと無いのでよくわかりませんが便利そう。MvRxや他のairbnb製のライブラリと相性が良さげです。

デバッグ関連

Log代替

timber

https://github.com/JakeWharton/timber

android.util.Logのラッパーです。誰も教えてくれないけどみんな使ってます(主観)。ビルドタイプによる機能の切り替えなどができます。

メモリ管理

leakcanary

https://github.com/square/leakcanary

信頼と実績のsquare製。アプリのメモリリークを検出し、通知します。当たり前のように使われている感じがします。

通信ログ周り

stetho

https://github.com/facebook/stetho

okhttpに噛ませるとChromeで通信ログなどが見れます。めちゃ便利。

flipper

https://github.com/facebook/flipper

Facebook製。Android以外のプラットフォームでも使えます。使ってる人見たことないです。stethoで良くね?

その他

Hyperion-Android

https://github.com/willowtreeapps/Hyperion-Android

色々できます。詳しくはこちらの記事を見てください。

DI

Dependency Injectionの略です。最近は知ってて当たり前感があります。参考

dagger2

https://github.com/google/dagger

square発google製。めちゃくちゃ使われてます。学習コストはかなり高いと思います。

koin

https://github.com/InsertKoinIO/koin

kotlin実装のDIライブラリ。知名度も上がってきて勢いを感じます。daggerよりわかりやすいので私は好きです。

テスト周り

mockito

https://github.com/mockito/mockito

モッキングフレームワークです。デファクト感があります。

mockk

https://github.com/mockk/mockk

kotlin実装のモッキングライブラリです。最近見かけるようになりました。

その他

ThreeTenABP

https://github.com/JakeWharton/ThreeTenABP

Androidで日付を簡単に扱えるライブラリ。誰も教えてくれないけど大変便利で使ってる人も多いはず。

所感

  • Java -> Kotlinの流れを強く感じます(koinとか)
  • 最近のAndroid開発ではdaggerやRxなど学習コストの高いものを覚える必要があり、開発を始める敷居が高くなっているように思います
  • 「これはみんな使ってるっしょ!」みたいなライブラリがあれば是非教えてください
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Android の Camera2 API と Mobile Vision API を使って 顔検出する

Android の Mobile Vision API を使って 顔検出する
の続きです。

概要

前回の記事では、画像ファイルから顔検出した。
今回の記事では、カメラからの連続画像から顔検出する。

公式サンプルコードでは、カメラの制御に
Mobile Vision API の CamearaSource を使っている。

この記事では、CamearaSource と同様の機能を持つ Cameara2Source を自作する。

reference: CameraSource

Android の Camera2 API を使って カメラのプレビュー画面を表示する
にて紹介し下記のコードを参考にした

Basic functionalities of both Camera1 API and Camera2 API with a Google Vision Face Detector added

カメラからの連続画像から顔検出する

画像ファイルから顔検出する場合は、Frame.Builder#setBitmap を使用した。

カメラからの連続画像から顔検出する場合は、Frame.Builder#setImageData を使用する。

reference: Frame.Builder#setImageData

画像は、NV21形式のバイト配列で指定する。

カメラからは YUV_420_888 形式で取得し、 NV21形式に変換する。

ImageReader

カメラからの連続画像をキャプチャーするための ImageReader を生成する。

ImageReader の使い方は、下記の記事を参考に。
Android の Camera2 API を使って 写真を撮る

// YUV_420_888 形式の画像の大きさを取得する
    StreamConfigurationMap map = characteristics.get(
        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
    Size imagePreviewSize = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)), new CompareSizesByArea());

// YUV_420_888 形式のImageReader を生成する
    ImageReade imageReaderPreview = ImageReader.newInstance( imagePreviewSizegetWidth(), imagePreviewSize.getHeight(), ImageFormat.YUV_420_888, 4);

// リスナーを設定する
    imageReaderPreview.setOnImageAvailableListener(previewAvailableListener, mBackgroundHandler);

// リスナー
    ImageReader.OnImageAvailableListener previewAvailableListener = new ImageReader.OnImageAvailableListener() {
        @Override
        public void onImageAvailable(ImageReader reader) {
    // 連続画像を FrameProcessor に渡す
            frameProcessor.setNextImage(reader.acquireNextImage());
        } 
    }; 

FrameProcessor

カメラからの連続画像を受け取り FaceDetector に渡すためのクラスです。
基底となるクラスはないので、スクラッチから自作する。

class Camera2FrameProcessor implements Runnable {

    public void setNextImage(Image image ) {
        // カメラからの連続画像を受け取る
    }

    @Override
    public void run() {
        // 連続画像を FaceDetector に渡す
        detector.receiveFrame(outputFrame);
    }
}

FaceTracker

FaceDetector から顔検出の結果を受け取るためのクラスです。
Tracker を継承して FaceTracker クラスを作成する。

reference: Tracker

onUpdate に結果が入る。

class FaceTracker extends Tracker<Face> {

        @Override
        public void onUpdate(FaceDetector.Detections<Face> detectionResults, Face face) {
            // 顔検出の結果の処理
        }
}

検出した顔の上にランドマークを表示する

下記の記事と同じような処理を行う。
Android の Camera2 API を使って 顔検出する

ViewGroup を継承した CameraSourcePreview を作成する。
CameraSourcePreview の子のビューとして、カメラのプレビュー画面を表示する TextureView とランドマークを表示するオーバーレイ用の View を作成する。

View の大きさに合うように、View と ImageReader の大きさの比率を求め、ランドマークの位置を調整する。

スクリーンショット

vision2.png

サンプルコードをgithub に公開した。
https://github.com/ohwada/Android_Samples/tree/master/Vision2

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む