- 投稿日:2020-10-09T19:07:41+09:00
TermuxでFirebaseを使いたい
背景
※執筆時点のfirebase-toolsは8.12.0です。
TermuxでFirebaseのエミュレータを起動したかった。
Termuxでもfirebase-toolsが入れられるので、firebase emulatorsも当然使えると思ったがそうはいかなかった。
firestoreとdatabaseのエミュレータはJavaで実装されているが、TermuxにはJavaが用意されていないため起動できない。そこで、Javaのインストールから
firebase emulators:start --only firestore
を起動できるまでの手順を紹介する。手順
0. 準備
既に一通り済んでいる場合は飛ばす。
Termux
PlayストアからTermuxをインストールする。
Termuxパッケージ
最低限以下のパッケージが必要になるので、Termux上でインストールする。
- proot
- wget
- vimなどのテキストエディタ
- nodejsまたはnodejs-lts
- firebase-tools
1. Javaのインストール
前述の通り、Javaが用意されておらずパッケージもない。
しかし、Termux-Javaと言うスクリプトを使えば一応Javaが使えるようになる(一応とした理由は後述する)。$ wget https://raw.githubusercontent.com/MasterDevX/java/master/installjava && bash installjavaこれでJavaが使えるようになる…はずだが、筆者の環境では
Bad system call
と言うログとともにJavaがkillされた。
Issueによればroot権限が必要なようなので、proot
を併用して起動するか確認する1。$ proot java
2. firebase-tools(firestoreエミュレータ)の修正
firestore及びdatabaseのエミュレータはjarファイルで提供されており、javaコマンドで実行するようになっている。
この時、javaコマンドはchildProcess.spawn()
を使って実行しているが、PATH
からjavaコマンドを探して実行するため、仮にaliasでproot java
に設定していたとしても関係なく素のjavaコマンドを実行し、Bad system call
で起動に失敗する。なので、ここは少し強引だがfirebase-toolsのソースコードを直接編集して対応する。
編集対象となるファイルはdownloadableEmulators.tsなので、ローカル環境でこのファイルを捜索してテキストエディタで開く。
firebase-toolsをグローバルにインストールしている場合は、デフォルトでは
/data/data/com.termux/files/usr/lib/node_modules/firebase-tools/lib/emulator/downloadableEmulators.jsとして存在している(はず)。
118行目、124行目あたりを以下の通りに修正する。
Line: 118 database: { - binary: "java", - args: ["-Duser.laungage=en", "-jar", getExecPath(types_1.Emulators.DATABASE)], + binary: "proot", + args: ["java", "-Duser.laungage=en", "-jar", getExecPath(types_1.Emulators.DATABASE)], Line: 124 firestore: { - binary: "java", - args: ["-Duser.laungage=en", "-jar", getExecPath(types_1.Emulators.FIRESTORE)], + binary: "proot", + args: ["java", "-Duser.laungage=en", "-jar", getExecPath(types_1.Emulators.FIRESTORE)],要するに、javaではなくprootを実行し、引数としてjavaを渡すように変更する。
3. 確認
これでエミュレータが動作するはずなので、プロジェクトディレクトリに戻ってエミュレータを起動する。
$ firebase emulators:start --only firestore問題点
エミュレータ終了時にjavaのプロセスが残る
エミュレータの終了に失敗し、firebaseプロセスの子プロセスであるはずのjavaが残り続けてしまう。
このjavaプロセスは8080ポートを占有しており、続けてエミュレータを起動しようとすると8080ポートが空いていないことによってエミュレータが起動できなくなってしまう。現時点では原因がわかっていないため、都度プロセスをkillして対応する2。
$ lsof -i:8080 # -> 8080を占有するjavaプロセスのpidがわかるはずである。プロセスがない場合は問題が発生していないので、そのままエミュレータを起動できる。 $ kill javaプロセスのpidfirebase-toolsのコードを編集している
編集せずにうまいことやる方法があったら教えてください。
ブラウザの開発ツールがない
この記事の主題とは直接関係ないが、hostingエミュレータを使えば作ったソースコードをlocalhostで閲覧できる。
しかし、閲覧に使用するブラウザはAndroidアプリなので開発ツールがなく、デバッグできない。参考
解決に時間がかかったので、残っていたタブから抜粋。実際にはもっとたくさんのページを閲覧した。
- https://termux.com/
- https://firebase.google.com/
- https://github.com/firebase/firebase-tools
- https://github.com/MasterDevX/Termux-Java/issues/7
- https://qiita.com/shintarogit-on-qiita/items/70f193829f4360dca771
- javaコマンドをどのようにして起動しているかを調べた。
- https://swfz.hatenablog.com/entry/2019/10/07/001242
- patch-packageでうまいことしたかったが、グローバルインストールだったので断念した。ローカルならいけるかもしれない。
- https://qiita.com/tacchi/items/a532aafd9c05fdf7be45
- Termuxのセットアップの参考にした。
- Ubuntu(LXDE, TermuxとUserLAndの両環境)も試したが動作が重く、Firefoxに何も表示されなかったので断念した。デスクトップが快適に動く環境ならLinux版のブラウザが使えるので開発ツールも使えるはず。
- https://knowledge.sakura.ad.jp/21687/
- 筆者はそもそもvimmerではない。しかし、恐れていたほどではなかった(傲慢)。
- 投稿日:2020-10-09T18:26:34+09:00
[Android]PUSH通知
概要
ローカル通知について結構前に勉強したことがあった(リモート通知はどうすればいいのか知らなかった)のだが、
だいぶ忘れた状態で、リモート通知のコード見ててどういうことなの・・・・となって、
なるほどねとなるまでにかなり時間がかかったのでメモPUSH通知とは
- PUSH通知はその発火トリガーによってローカル通知とリモート通知に分類されている。
- ローカル通知:発火トリガーがローカルのなにかの処理
- リモート通知:発火トリガーがFCMからのメッセージ受信
- PUSH通知の本質的な処理・・・すなわち「通知領域への表示」〜「通知タップ時の画面遷移処理」のやり方は全く同じ ←ここがわかってなかった
- なお、単純にPUSH通知という場合はリモート通知のことを指すことが多い。 ←さらにここでやられた
- FCMメッセージ送信=PUSH通知と捉えている記事が世にめちゃくちゃ多いが、コレ多分嘘で、ここが理解を妨げていたんだと思う。
Qiita記事とかでFirebaseからPUSH通知を送信!みたいな図をよく見かけてたせいで、完全にだまされた。 ←こいつが主原因!!!
Firebase公式でPUSH通知なんていう言葉出てこないもの。送るのはあくまでFCMメッセージだっていってるもの。
リモート通知
- FCMから受けたメッセージを処理するには、FirebaseMessagingService() を継承したクラスを作成する必要あり。
- FCMから通知が来た時に呼ばれるのは onMessageReceived(remoteMessage: RemoteMessage) っぽい。
- ここを起点にPUSH通知の処理を書けばOK
- remoteMessage.getData()で、PUSH通知に含まれていたペイロード(※)データ(Map型)を取得できる
※ペイロード:ヘッダを抜いたデータ本体のこと。httpレスポンスでいうところのbodyだと理解。
- 投稿日:2020-10-09T16:23:11+09:00
[Android]scrcpy でミラーリングすると画面が見切れる問題の対処方法
はじめに
scrcpy は Android 端末をミラーリング、画面操作をUSBまたはTCP/IP経由で行うアプリケーションです。Windows・Linux・Macで利用できるアプリケーションなので全てのAndroid開発環境で利用できます。scrcpy はかなり便利なツールでバグも少ないのですが次の問題があったので解決方法を共有します。
問題
解像度が 1920x1200 のを scrcpy でミラーリングすると、なぜか 1920x1080 の解像度でミラーリングされ画面が見切れて表示されてしまう。本来であれば scrcpy ではタップ操作もサポートしているが、この状態になるとタップ操作もできなくなる。
$ scrcpy 2020-10-09 15:40:18.220 scrcpy[7021:244757] INFO: scrcpy 1.10 <https://github.com/Genymobile/scrcpy> /usr/local/Cellar/scrcpy/1.10/share/scrcpy/scrcpy-server.jar: 1 file pushed. 1.3 MB/s (22662 bytes in 0.017s) 2020-10-09 15:40:19.995 scrcpy[7021:244757] INFO: Initial texture: 1920x1200 2020-10-09 15:40:20.488 scrcpy[7021:244757] INFO: New texture: 1920x1080
※ 画面下部のナビゲーションバーとボタンが切れて表示されてしまっている。解決方法
scrcpy でミラーリングする際に 1280x800 の解像度で小さく表示するようにしてやる。ミラーリングの解像度は -m オプションで設定できるようになっています。なので次のように -m オプションを設定してやると見きれずに表示してくれます。また -m オプションを設定することでタッチ操作も正常に動作するようになります。
$ scrcpy -m 1280 2020-10-09 15:52:08.956 scrcpy[7177:254315] INFO: scrcpy 1.10 <https://github.com/Genymobile/scrcpy> /usr/local/Cellar/scrcpy/1.10/share/sc...shed. 2.0 MB/s (22662 bytes in 0.011s) 2020-10-09 15:52:09.897 scrcpy[7177:254315] INFO: Initial texture: 1280x800
※ 画面下部のナビゲーションバーとボタンが切れずに表示できている。おわりに
scrcpy は便利なツールで殆どの端末で正常に動作するのですが、稀に手く動作しない端末があるみたいです。動作しない端末に遭遇した場合は本記事で紹介した解決方法を試してみると良いかなと思います。
参考記事
- 投稿日:2020-10-09T15:40:11+09:00
新しい Google Play Console では「サービスとAPI」というメニューは別の名前になっています
概要
今までの GooglePlayConsole は 2020年11月2日 をもってサービスを終了し、新しい GooglePlayConsole になります。
最近は新しい方の GooglePlayConsole に使っていました。
新しいと言ってもまあだいたい雰囲気で問題なく使えていたのですが、従来の GooglePlayConsole でいうところの以下のメニューが行方不明に…
開発ツール - サービスとAPI
どこにいったのかわからず、調べようにも検索ワードが微妙すぎてうまく検索できず、
ドキュメントを見ても従来の GooglePlayConsole のスクリーンショットがはられており困っていたのですが、
さっきたまたまメニューをポチポチしてたら見つけることができました。めんどくさがらずに、最初から全部のメニューをポチポチしておけばよかった…
ちなみに、一度新しい GooglePlayConsole に切り替えたとしても、サービス終了するまでは
「従来の Play コンソールを使用」というところから今までの GooglePlayConsole を使うことはできます。しかし従来の GooglePlayConsole が使えなくなったら「どこから設定するのかわからない!」となってしまうのでどうしても見つけたかった次第です。
場所
従来の GooglePlayConsole の「サービスとAPI」には以下の4項目がありました。
- ライセンスとアプリ内課金
- リアルタイム デベロッパー通知
- Google Play ゲーム サービス
- Google 検索のインデックスにアプリを登録
それぞれ新しい GooglePlayConsole ではどこにあるのかを書いておきます。
ライセンスとアプリ内課金、リアルタイム デベロッパー通知
こちらの2つは同じ画面内にあります。
収益化 - 収益化のセットアップ
Google Play ゲーム サービス
検索ボックスに「ゲーム」と入力 - Play ゲームサービスの設定
(こちらはメニューから遷移する方法がわかりませんでした…)Google 検索のインデックスにアプリを登録
設定 - 詳細設定 - アプリのインデックス登録
- 投稿日:2020-10-09T15:40:11+09:00
新しい Google Play Console では「サービスとAPI」というメニューは別の名前になっていた
概要
今までの GooglePlayConsole は 2020年11月2日 をもってサービスを終了し、新しい GooglePlayConsole になります。
最近は新しい方の GooglePlayConsole に使っていました。
新しいと言ってもまあだいたい雰囲気で問題なく使えていたのですが、従来の GooglePlayConsole でいうところの以下のメニューが行方不明に…
開発ツール - サービスとAPI
どこにいったのかわからず、調べようにも検索ワードが微妙すぎてうまく検索できず、
ドキュメントを見ても従来の GooglePlayConsole のスクリーンショットがはられており困っていたのですが、
さっきたまたまメニューをポチポチしてたら見つけることができました。めんどくさがらずに、最初から全部のメニューをポチポチしておけばよかった…
ちなみに、一度新しい GooglePlayConsole に切り替えたとしても、サービス終了するまでは
「従来の Play コンソールを使用」というところから今までの GooglePlayConsole を使うことはできます。しかし従来の GooglePlayConsole が使えなくなったら「どこから設定するのかわからない!」となってしまうのでどうしても見つけたかった次第です。
場所
従来の GooglePlayConsole の「サービスとAPI」には以下の4項目がありました。
- ライセンスとアプリ内課金
- リアルタイム デベロッパー通知
- Google Play ゲーム サービス
- Google 検索のインデックスにアプリを登録
それぞれ新しい GooglePlayConsole ではどこにあるのかを書いておきます。
ライセンスとアプリ内課金、リアルタイム デベロッパー通知
こちらの2つは同じ画面内にあります。
収益化 - 収益化のセットアップ
Google Play ゲーム サービス
検索ボックスに「ゲーム」と入力 - Play ゲームサービスの設定
(こちらはメニューから遷移する方法がわかりませんでした…)Google 検索のインデックスにアプリを登録
設定 - 詳細設定 - アプリのインデックス登録
- 投稿日:2020-10-09T15:40:11+09:00
新しい Google Play Console では「サービスとAPI」というメニューは別の名前になっていた件
概要
今までの GooglePlayConsole は 2020年11月2日 をもってサービスを終了し、新しい GooglePlayConsole になります。
最近は新しい方の GooglePlayConsole に使っていました。
新しいと言ってもまあだいたい雰囲気で問題なく使えていたのですが、従来の GooglePlayConsole でいうところの以下のメニューが行方不明に…
開発ツール - サービスとAPI
どこにいったのかわからず、調べようにも検索ワードが微妙すぎてうまく検索できず、
ドキュメントを見ても従来の GooglePlayConsole のスクリーンショットがはられており困っていたのですが、
さっきたまたまメニューをポチポチしてたら見つけることができました。めんどくさがらずに、最初から全部のメニューをポチポチしておけばよかった…
ちなみに、一度新しい GooglePlayConsole に切り替えたとしても、サービス終了するまでは
「従来の Play コンソールを使用」というところから今までの GooglePlayConsole を使うことはできます。しかし従来の GooglePlayConsole が使えなくなったら「どこから設定するのかわからない!」となってしまうのでどうしても見つけたかった次第です。
場所
従来の GooglePlayConsole の「サービスとAPI」には以下の4項目がありました。
- ライセンスとアプリ内課金
- リアルタイム デベロッパー通知
- Google Play ゲーム サービス
- Google 検索のインデックスにアプリを登録
それぞれ新しい GooglePlayConsole ではどこにあるのかを書いておきます。
ライセンスとアプリ内課金、リアルタイム デベロッパー通知
こちらの2つは同じ画面内にあります。
収益化 - 収益化のセットアップ
Google Play ゲーム サービス
検索ボックスに「ゲーム」と入力 - Play ゲームサービスの設定
(メニューから遷移する方法がわかりませんでした…)Google 検索のインデックスにアプリを登録
設定 - 詳細設定 - アプリのインデックス登録
- 投稿日:2020-10-09T08:29:51+09:00
Kotlin Multiplatform Mobile がアルファ段階に移行したので、チュートリアルを試す
背景
最近、Kotlin Multiplatform Mobile(KMM)がアルファ段階に移行したようです。
Kotlin Multiplatform Mobile がアルファ段階に移行 – Kotlin Blog | JetBrains
KMM とは、JetBrains が提供するクロスプラットフォーム対応のモバイル開発用 SDK です。
Kotlin のマルチプラットフォーム対応能力を駆使し、モバイルアプリケーションの構築体験を可能な限り楽しく効率的にするように設計されたさまざまなツールや機能を含んでいます。見ていて面白そうだったので、試しにチュートリアルをやってみました。
※2020 年 10 月時点の情報なので、今後のアップデートにより変わる可能性があります。開発環境
開発環境は以下の通りです。
- Android Studio 4.1 RC 3 以降
- Xcode 11.3 以降
- Kotlin 1.4.0 以降
- Java 1.8.0_73 以降
- macOS Catalina バージョン 10.15.6
環境構築
以下をベースに進めていきます。
Getting started - Help | Kotlin Multiplatform Mobile Docs
Android Studio version 4.1 RC 3 以降をインストール
Android Studio Previewから、4.1 RC 3 か 4.2 CANARY 13 のいずれかをインストールします。
どちらでも大丈夫です。Kotlin のバージョンを 1.4.0 以降にアップデート
Configure
->Plugins
から、Kotlin を 1.4.0 以降にアップデートします。Kotlin Multiplatform Mobile をインストール
Configure
->Plugins
から、Kotlin Multiplatform Mobile をインストールします。インストール後、Android Studio を再起動します。
はじめてのマルチプラットフォームアプリ作成
以下をベースに進めていきます。
Create your first multiplatform application - Help | Kotlin Multiplatform Mobile Docs
プロジェクト作成
Create New Project
から新規でプロジェクトを作成します。
Select a Project Template
より、KMM Application
を選択し、Next
をクリックします。各項目を以下の通り入力します。
項目 名称 Name KMM Application Package name com.example.kmmapplication Save location 任意のフォルダ
Configure Activity
ではデフォルトのままFinish
をクリックします。ビルド
早速ビルドしてみます。
まずは Android から。
androidApp
を選択してから、ビルド対象の端末を設定してビルドします。すると、以下のように起動します。
次に iOS を試してみます。
iosApp
を選択し、Edit Confiugrations...
をクリックします。
Execution target
で端末を設定し、ビルドします。すると、以下のように起動します。
テストコード
各プラットフォームごとにテストコードが用意されており、それぞれ以下のようにファイルを開いて実行できます。
Android のほうは、
shared/src/androidTest/kotlin/com.example.kmmapplication.shared
のandroidTest.kt
にあります。package com.example.kmmapplication.shared import org.junit.Assert.assertTrue import org.junit.Test class AndroidGreetingTest { @Test fun testExample() { assertTrue("Check Android is mentioned", Greeting().greeting().contains("Android")) } }iOS のほうは、
shared/src/iosTest/kotlin/com.example.kmmapplication.shared
のiosTest.kt
にあります。package com.example.kmmapplication.shared import kotlin.test.Test import kotlin.test.assertTrue class IosGreetingTest { @Test fun testExample() { assertTrue(Greeting().greeting().contains("iOS"), "Check iOS is mentioned") } }どちらも
Greeting().greeting()
が出力する文字列にプラットフォーム名が含まれているかのテストをしています。
shared/src/commonTest/kotlin
という共通用のテストフォルダも用意されているようですが、デフォルトでは何も入っていませんでした。アプリケーションの更新
画面上では「Hello, [プラットフォーム名とバージョン]」という文字列が表示されていました。この文字列を生成しているクラスが
shared/src/commonMain/kotlin/com.example.kmmapplication.shared
のGreeting.kt
にあります。package com.example.kmmapplication.shared class Greeting { fun greeting(): String { return "Hello, ${Platform().platform}!" } }このディレクトリには、Android と iOS の両方のプラットフォームの共有コードが保存されます。共有コードに変更を加えると、両方のアプリケーションに変更が表示されます。
試しに以下のように変更してみます。class Greeting { fun greeting(): String { return "Guess what it is! > ${Platform().platform.reversed()}!" } }変更後、各プラットフォームでビルドしてみます。
いずれも変更が反映されていることを確認しました。
Android iOS 最後に、Platform クラスについても確認してみます。
commonMain/kotlin/com.example.kmmapplication.shared
のPlatform.kt
です。package com.example.kmmapplication.shared expect class Platform() { val platform: String }
expect
キーワードはマルチプラットフォーム専用のインタフェースにて使われるキーワードで、あるプラットフォームのクラスを使いたい場合に使うキーワードです。
androidMain
とiosMain
にもそれぞれPlatform.kt
があります。Android のほうは、
androidMain/kotlin/com.example.kmmapplication.shared
のPlatform.kt
です。package com.example.kmmapplication.shared actual class Platform actual constructor() { actual val platform: String = "Android ${android.os.Build.VERSION.SDK_INT}" }iOS のほうは、
iosMain/kotlin/com.example.kmmapplication.shared
のPlatform.kt
です。package com.example.kmmapplication.shared import platform.UIKit.UIDevice actual class Platform actual constructor() { actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion }それぞれ
actual
キーワードが使われています。プラットフォームごとに、expect
クラスをactual
で実装する必要があります。
interface
とそれをimplement
するclass
の関係に似ています。まとめ
Kotlin Multiplatform Mobile(KMM)がアルファ段階に移行したことを受けて、試しにチュートリアルをやってみました。
どうやら共通化するのはロジックのみで、UI は各プラットフォームごとに独自で実装する必要がありそうです。
さらに以下のようなハンズオンも用意されているので、時間があるときにまた試してみます。Hands-on: Networking and Data storage - Help | Kotlin Multiplatform Mobile Docs
参考 URL
- 投稿日:2020-10-09T07:41:08+09:00
#3 Kotlin Koans Introduction/Default arguments 解説
1.はじめに
Kotlin公式リファレンスのKotlin Koans/Default argumentsの解説記事です。
Kotlin Koansを通してKotlinを学習される人の参考になれば幸いです。
ただし、リファレンスを自力で読む力を養いたい方は、
すぐにこの記事に目を通さないで下さい!一度各自で挑戦してから、お目通し頂ければと思います
2-1.Default引数とnamed引数
#2 Kotlin Koans Introduction/Named arguments 解説 の記事で説明しておりますので、ご覧ください。
2-2.toUpperCase()
右側の本文中に出てくる、toUpperCase()関数をKotlin公式リファレンスで見てみましょう。
fun String.toUpperCase(locale: Locale):String
Returns a copy of this string converted to upper case using the rules of the specified locale.
つまり、String型のインスタンスがtoUpperCase()関数を呼び出すと、インスタンスが大文字になって返ってくる。
ということになります。
(※本Koansのなかには、Boolean型のパラメータとしてもtoUpperCaseが出てきます。)
3.Introduction/Default argumentsの解説
Kotlin Koans Introduction/Default argumentsの解説です。
随時本サイトの内容を引用させていただきます。右側の本文を見てみましょう。
There are several overloads of 'foo()' in Java:
public String foo(String name, int number, boolean toUpperCase) { return (toUpperCase ? name.toUpperCase() : name) + number; } public String foo(String name, int number) { return foo(name, number, false); } public String foo(String name, boolean toUpperCase) { return foo(name, 42, toUpperCase); } public String foo(String name) { return foo(name, 42); }All these Java overloads can be replaced with one function in Kotlin. Change the declaration of the function foo in a way that makes the code using foo compile. Use default and named arguments.
上記4種のオーバーロードされたfoo()関数(Javaで定義されている。)を、Kotlinを用いることで4種の関数の機能を1種の関数でまとめることができる。default引数、named引数を用いてfoo()関数を定義しなさい。
といった内容になります。
以下から具体的な解説です。
まず、一番上のfoo()関数の
toUpperCase ? name.toUpperCase() : nameは、toUpperCaseがtrueならname.toUpperCase()をfalseならnameを値として指定するといった意味です(Javaの内容なので解説は省略します。)。
4種のfoo()関数を見てみましょう。
下3種のfoo()関数は戻り値のなかで1番上のfoo()関数を呼び出しているのがわかります。
(正確には1番下のfoo()関数は下から3番目のfoo()関数を間に挟んでいます。)このとき下3種いずれのfoo()関数を呼び出したときでも、1番上のfoo()関数の引数numberに42を引数toUpperCaseにfalseを渡しています。
そして、1番上のfoo()関数がtoUpperCaseの真偽値(trueかfalse)に対応する値を返しています。
つまり、foo()関数の呼び出しもとが
引数numberとtoUpperCaseに値を渡さなければ、デフォルトで42とfalseが渡されることになっているといるわけです。「デフォルトで渡される引数が決まっているのなら、初めに設定しておこう!」ということで、
Kotlinでfoo()関数を書き換えるときに、Default引数を利用して
number : Int = 42,toUpperCase : Boolean = falseと書き加えればいいわけですね。
そうすることで、
foo("a") foo("b",number = 1) foo("c",toUpperCase = true) foo(name = "d",number = 2,toUpperCase = true)いずれのfoo()関数の呼び出し側にも対応できます。
4 最後に
次回はKotlin Koans Introducion/Lambdasの解説をします
- 投稿日:2020-10-09T07:38:13+09:00
#2 Kotlin Koans Introduction/Named arguments 解説
1.はじめに
Kotlin公式リファレンスのKotlin Koans/Named argumentsの解説記事です。
Kotlin Koansを通してKotlinを学習される人の参考になれば幸いです。
ただし、リファレンスを自力で読む力を養いたい方は、
すぐにこの記事に目を通さないで下さい!一度各自で挑戦してから、お目通し頂ければと思います
2-1.Default引数とnamed引数
Default引数:デフォルトで値が指定されている引数
named引数:名前がついた引数
Default引数は関数を呼び出す際、引数に値を指定しなくても良い、
named引数は、引数が複数あるとき、関数の呼び出し側が引数の順序を気にせず値を渡せる、
といったメリットがあります。Default引数とnamed引数の詳細(公式レファレンスの引用)
2-2.関数定義の略記
fun joinOptions(options: Collection<String>) = options.joinToString(TODO())を見てみると、関数の実行内容を記述する
{}
と、(options: Collection<String>)
と=
の間にあるはずの戻り値の型
が省略されています。じつは、Kotlinでは関数の戻り値を
=
の後に記述し、{}
の表現を省略できるというルールがあります。また戻り値の型の指定が省略されているのは、Kotlinの
型推論
という機能が働き、自動的に戻り値の値から型を判断しているのです。以上のことから、Kotlinの関数定義の略記は
fun 関数名(引数名:引数の型) = 戻り値となります。
3.Introduction/Named argumentsの解説
Kotiln Koans Introduction/Named argumentsの解説です。
随時本サイトの内容を引用させていただきます。まずは、右側の本文を見てみましょう。
Default and named arguments help to minimize the number of overloads and improve the
readability of the function invocation. The library function
joinToString
is declared withdefault values for parameters:
fun joinToString( separator: String = ", ", prefix: String = "", postfix: String = "", /* ... */ ): StringIt can be called on a collection of Strings. Specifying only two arguments make the function
joinOptions()
return the list in a JSON format (e.g., "[a, b, c]")default引数とnamed引数はオーバーロードの数を最少化し、関数実行の際の可読性を高める。
ライブラリのjoinToString()関数は、デフォルトの値が引数に設定されて宣言されている。
この関数はString型のコレクションから呼び出すことができる。
2個の引数を設定してjoinOptions()関数がlistをJSONフォーマットで返すようにしなさい。と書かれています。
つまり、左側の
fun joinOptions(options: Collection<String>) = options.joinToString(TODO())という式の
TODO()
部分に適切な引数を渡し、listをJSONフォーマットで返すようにしなさい。ということになります。
joinToString()関数は、
- 引数separatorには, が
- 引数prefixとpostfixには空文字が
指定されています。
(いずれの引数も名前があり値が入っていますので、default引数かつnamed引数ですね。)
本文中の例のようなJSONフォーマット[a, b, c]をつくるには、引数として
[
と]
を指定する必要があります。ですので、
TODO()の箇所を
prefix = "[",postfix = "]"
とすればいいですね。
最後に
次回はKotlin Koans Introducion/Defalut argumentsの解説をします
- 投稿日:2020-10-09T00:51:31+09:00
Quick Appの開発方法
前書き
日本ではQuick Appがあまり知られていません。しかし、Quick Appはすでに170ヶ国以上展開されています。本稿はQuick Appの特徴と開発手順を紹介するものです。
Quick Appの概要
ユーザーがAndroid上で動かすサービスが主に2つあります。
- ネイティブアプリ(Androidアプリ)
- ウェブアプリ(ブラウザでウェブサイトを開く)
さらにQuick Appを加えれば、合計3つあります。
Quick Appの開発方法を述べる前に、ネイティブアプリとウェブアプリとQuick Appの特徴を比べてみたいです。
ネイティブアプリの特徴
- インストールが必要
- デバイス機能が使用可能
- リリース時の審査あり
- iOS同時対応不可
- 開発言語(Java、Kotlin)
- APKの容量が大きい(数十MB以上のアプリが多く、100MBを超えるアプリも少なくない)
ウェブアプリの特徴
- インストールが不要
- デバイス機能が使用不可
- リリース時の審査なし
- iOS同時対応可
- 開発言語(HTML、CSS、JS)
- 容量が小さい
Quick Appの特徴
- インストールが不要
- デバイス機能が使用可能
- リリース時の審査あり
- iOS同時対応不可
- 開発言語(HTML、CSS、JS)
- 容量が4MBまで
性能比較
ネイティブアプリ、ウェブアプリ、Quick Appの性能調査結果が次の通りです。
まとめ
ネイティブアプリ ウェブアプリ Quick App インストールの有無 必要 不要 不要 デバイス機能の使用 可能 不可 可能 リリース時の審査 あり なし あり iOS同時対応 不可 可能 不可 アプリのサイズ 大きい 小さい 小さい 起動時間 遅い 速い 速い 操作性 良い 普通 良い メモリ使用量 少ない 多い 少ない AppGalleryのQuick Appの紹介
Quick AppはAppGalleryで検索できます。AppGalleryがインストールされていない方は、こちらのページ(AppGallery をインストールするにはどうすればよいでしょうか)を参考に、AppGalleryをダウンロードし、インストールしておいてください。
AppGalleryを開き、QuickAppをタップします。
ここでさらに検索をかけます。実行したいQuick Appは”開く”ボタンをタップして実行します。
Quick App終了時に、そのQuick Appを追加しておくと、次回起動するときに便利です。
Quick Appの開発手順
Quick Appの開発手順はAndroidアプリのとほとんど同じです。それでは、詳しい手順を説明しましょう。
Quick Appの開発環境
Quick Appを開発するのに、以下のものが必要です。それらをダウンロードしてインストールしてください。
AppGallery Connect側の作業
AppGallery Connect側の作業はHMS Account Kit実装入門の前準備をご参照ください。ただ、注意しなければならないのは、アプリの追加画面でQuick Appを選ぶことです。
Huawei quick app IDE
Huawei quick app IDEを起動し、“New Project”をクリックします。
“App Name”と“Package Name”を設定します。
簡単なQuick Appの作り方を示したいので、Templateでは今回はHTML5 Appを選びます。
OKボタンをクリックしたら、プロジェクトが生成され、次のような画面に遷移します。
コーディングに入る前に、指紋ボタンをクリックし、署名を設定しておきます。
署名が作成されたら、証明書が/sign/releaseに格納されます。
ここでさらに/sign/debugフォルダを作り、/sign/releaseにあるcertificate.pemとprivate.pemをここにコピーします。
もう一度指紋ボタンをクリックします。クリックしたら、Fingerprint(公開鍵暗号)が表示されます。それをコピーします。
AppGallery Connectの[My Projects] -> [General information] -> [App information] -> [SHA-256 certificate fingerprint]に、コピーした公開鍵暗号をセットします。
Quick Appのコーディング
Quick Appはウェブアプリと同じく、HTML、CSS、JSで開発します。ウェブアプリの開発経験がある方なら、すぐ慣れると思います。
プロジェクトの構成
プロジェクトは次のパーツより構成されます。
- manifest.json
- app.ux
- /Common/[リソースファイル]
- /[ページ名]/[ページ名のuxファイル]
詳しくはこちらをご参照ください。
Quick App Referencemanifest.json
基本的にAndroidManifest.xmlと同じものだと考えればよいです。
app.uxファイル
すべてのページ(app.ux以外のuxファイル)に使われるものはここで定義します。
uxファイル
uxファイルはtemplateとstyleとscriptで構成されます。それぞれのブロックのプログラミング言語が違います。templateはhtml5、styleはcss、scriptはjavaScriptになります。
Quick Appのサンプル
試しに楽天市場のQuick Appを作ってみましょう。
まずloadUrlの値を "https://www.rakuten.co.jp/" に変えます。
Huawei Quick App LoaderがAndroid端末にインストールされていない場合はダイアログが出ます。ここでインストールします。
楽天市場が出てきました。右上のフローティング操作ボタンをドラッグして別の場所に移動できます。
終わり
Quick Appは高いポテンシャルを秘めているので、皆さんもぜひ試してみてください。
参考ページ