3 週間ほど前に、AMP Fest を初開催しました。そこでは、コミュニティがオンライン上に集結し、AMP の世界の最新情報やうれしい情報が共有されました。この AMP Fest では、新しい AMP Page Experience Guide のリリースや AMP For Email の新たなクライアントのサポートなど、AMP エコシステム全体に及ぶすばらしい進展の数々が発表されました。

イベントの基調講演を見直し、すべてのポイントを復習する

この記事では、AMP Fest を振り返り、皆さんが見逃してしまったかもしれないニュースをもれなくお届けします。

AMP とページ エクスペリエンス

AMP Fest で発表された最新情報の中でも、特に注目を集めたのは、優れたページ エクスペリエンスを実現するための作業でした。AMP はユーザーファーストなサイトの構築に役立ててもらうために開発されました。そのため、サイト運営者がすばらしいページ エクスペリエンスを作るうえで、費用対効果の高いシンプルなソリューションであると確信しています。それと合わせて、AMP ドメインの 60% が Core Web Vitals 指標に合格*していることもお知らせしました。一方で、同じ基準に合格した非 AMP ドメインは 12% に過ぎません。 

* ここでの「合格」とは、ドメインの 75% のページが Core Web Vitals 指標に合格したことを表します。

AMP とページ エクスペリエンスの詳細については、こちらを参照

AMP ページが 1 つ残らずこの指標に合格するという目標を達成できるように、AMP Page Experience Guide もリリースしました。これは、AMP ページのパフォーマンスの具体的な改善方法について、実際のアクションにつながる AMP 固有のフィードバックを提供してくれる新しいツールです。これにより、AMP ページがページ エクスペリエンス シグナルを満たさない場合に、アクションにつながるフィードバックを提供するか、最後の手段としてパフォーマンスの問題に対処する個人サポートを提供することを保証できるようになります。

新しい AMP Page Experience Guide による AMP ページのテストはこちらから

Web Stories

今年、AMP Stories の名称を Web Stories に変更することをお知らせしました。これは、#nocode ツールを使ってこのフォーマットを活用しているクリエイターやコンシューマーが増加している状況を受けてのことです。それ以来、サイト運営者やウェブ クリエイターによるこのフォーマットの採用が続いています。

サイト運営者やウェブ クリエイターによる Web Stories フォーマットの採用が続いている

この勢いに乗り、カスタマイズ可能なクイズ、投票機能、360 度動画の組み込み、高機能なオープンソース Story Player を使って Web Stories をサイトに直接埋め込む機能など、Web Stories フォーマットの最新アップデートについてお知らせしました。これは、Google の Web Stories チームからの Discover に Web Stories が登場するという最近の発表に続くものです。Discover は Android および iOS の Google 製アプリの一部で、毎月 8 億人以上が利用しています。

AMP for Email

現在、AMP for Email の商用利用が始まって 1 年半以上が経過しています。そして今でも、毎日のようにダイナミック メールの新しいユースケースに驚かされています。AMP Fest では、Verizon Media(Yahoo Mail)が AMP のデベロッパー プレビューをリリースしたことをお知らせしました。そして、2021 年の第 1 四半期には、Salesforce Marketing Cloud に AMP メールが導入される予定です。数百万人の新しいユーザーにダイナミック メールをお届けできるのが楽しみです。 

AMP For Email の送信者が顧客に提供しているエクスペリエンスは実に見事なもので、私たちはそれをうれしく思っています。AMP Fest では、AMP メールを使って顧客やクライアントの時間や費用を節約している送信者を紹介しました。以下のトークで、さまざまな送信者がダイナミック メールを使って実現したすばらしい成果をご覧ください。

AMP For Email で成功したメール送信者を紹介するトーク

世界の AMP 成功事例

このイベントでは、とてもたくさんのうれしいニュースが発表されるとともに、すばらしいことに、AMP を使っている世界中のデベロッパーやサイトオーナーが、AMP の実装体験や AMP を最大限に活用するヒントを共有しました。 

Uno TV のソフトウェア エンジニアリング マネージャーである Violeta Rosales 氏は、このデジタル ニュース局がどのようにウェブサイトを AMP ファーストに移行したかについて説明しました。さらに、その移行作業の間に Uno TV が実際に体験したメリットや課題についてもお話ししています。 

リクルートのシニア ソフトウェア エンジニアである Yosuke Furukawa 氏は、AMP ファーストなウェブサイトを構築する際の手順やヒントを説明しました。さらに、Next.js などのフレームワークや、オフキャッシュ AMP などの運用戦略に関するトピックにも触れています。 

Televisa Digital の CTO である Antonio González de León 氏は、Televisa が AMP ファーストに移行した際の教訓を分かち合ってくれました。新しいサイト運営者やデベロッパーがベテランのメディア事業から学ぶことができる、その他の教訓も含まれています。 

JvM TECH の取締役である Thomas Feldhaus 氏は、AMP が広告代理店のウェブサイト作成プロセスを加速させるためにどう役立ったかについて話しました。しかも、実行時の高い品質は一貫して維持しています。 

そして最後に、Automattic のグロース エンジニアリング リードである Jason Caldwell 氏が、AMP ファーストによってどのように WordPress.com のコンバージョン率を上昇させ、獲得コストを下げて、WordPress.com の主なランディング ページのパフォーマンスを向上させたかについてお話ししました

ありがとうございました

この記事では紹介しきれないほどたくさんのすばらしいトークがありました。ぜひイベントのプレイリストを確認し、見直してみてください。イベントをこれほどの成功に導いてくださった皆さんに感謝します。AMP が誕生したのはわずか 5 年あまり前です。それ以来、AMP は大きく進化し、私たちはこれまで以上に AMP の明るい未来に期待しています。

投稿者: Alex Durán(AMP プロジェクト マーケティング、 Google)


Reviewed by Chiko Shimizu - Developer Relations Team

デジタル ウォレット vs 通常のカード決済

企業がデジタル ウォレットを採用すると、実際に具体的なメリットが得られます。たとえば、以下のようなものです。
  • 企業がデジタル ウォレット決済を利用すると、通常のカード決済と比べて、承認率は大幅に高く、拒否率は大幅に低くなります2
  • ほとんどのマーケットでは、デジタル ウォレットの決済総額はカードよりも低くなっていますが、2019 年の米国のデジタル ウォレット決済の価値は、通常のカード決済よりも平均 25% 高くなっています2

企業で Google Pay を導入する方法

デジタル ウォレットを採用し、お客様にシームレスな決済体験を提供する準備はできているでしょうか。導入はたった 4 段階の簡単なステップで完了します。こちらの Business Console でサインアップし、デベロッパー サイトにアクセスして詳しい情報を確認してください。こちらから、ホワイトペーパーの全編もご覧いただけます。他の企業が Google Pay を使ってどのように持続的な効果を実現したかを示す、これまでのケーススタディも掲載されています。
Business Console プロセスの図
ホワイトペーパーが気になった方は、以下の連絡先に直接ご連絡ください。

Google:

Steve Klebe

Google Pay、PSP パートナーシップ責任者

[email protected]

Worldpay:

Rami Josef

Worldpay、シニア プロダクト マネージャー

[email protected]

[1] - Worldpay by FIS Global Payments Report
[2] - 出典は、2018 年第 4 四半期から 2020 年第 1 四半期のデータを使用した Worldpay の Worldwide Payments Gateway(WPG)

ご意見をお寄せください

質問がある方は、以下のコメント欄か、#AskGooglePayDev を使ってツイートしてお知らせください。

Reviewed by Eiji Kitamura - Developer Relations Team


Google Cloud 放送番組 Cloud OnAir(木曜日 18:00 - 19:00 配信)は Google Cloud の製品を解説し、最新の情報などをいち早く皆様にお伝えする オンライン番組です。本年も残りわずかとなりましたがまだまだ放送が続きます。


12 月 3 日(木): Google Workspace でできるさまざまなデータ連携の活用術を解説します。スクリプト言語 Google Apps Script、スプレッドシートで大規模データ分析を可能にする Connected Sheets、そしてノーコード アプリ開発ツール AppSheet を使用した一連の流れを、デモを交えながらご紹介します。


12 月 10 日(木): Google Cloud パートナーであるヴイエムウェア株式会社をお招きし、Google Cloud VMware Engine と VMware Cloud の関係をお話していきます。従来よりも手軽に Lift & Shift が可能となり、さらにプロダクトの機能と連携させることで、より手軽にモダナイズすることができます。また VMware ソリューションの活用により一貫した運用管理も可能になります。この放送では実際の GCVE 環境の構築ステップとハイブリッド運用管理について、GCVE と VMware ソリューションのデモをお見せしながらご紹介します。


12 月 17 日(木): 株式会社マーケティングアプリケーションズ様は、企業向けにマーケティングリサーチサービスを提供しており、その中核となるリサーチプラットフォームをオンプレミスから Google Cloud に移行しました。この放送では、株式会社マーケティングアプリケーションズ様にご出演いただき、マイグレーション時の状況、その後の運用やコストなどの点で良かったこと、大変だったことなど赤裸々に語っていただきます。


放送中に実施する Q&A は、ページ上で皆様の疑問に Google Cloud の エキスパートがお答えします。わからないことや疑問に思ってることなどをぜひ投稿してください。


多くの方のご視聴をお待ちしております。


視聴申し込みページ : https://goo.gle/2HfWKQQ


※ ご視聴には視聴登録(各回)が必要です。


Posted by Takuo Suzuki - Developer Relations Team


Cloud OnBoard は、 認定トレーナーによる Google Cloud 無料トレーニングイベントです。

このトレーニングイベントに参加していただくことによって、開発者や IT プロフェッショナルの方々は Google Cloud のスキルセットを身につけることができます。

毎回ご好評いただいている「Cloud OnBoard」を、このたび新たなコンテンツで開催します。

「Google Cloud への移行講座」では、一般的に容易ではないと言われるクラウドへの移行戦略と Google Cloud の基礎について学習することができます。Google Cloud の基礎はもちろんのこと、具体的な移行プロセス(移行元環境の評価、クラウド ガバナンス、Anthos プラットフォーム、Google Cloud の仮想マシンと仮想ネットワーク、および物理マシンと仮想マシンをリフト & シフトするための適切な方法など)をわかりやすく説明します。

オンラインでの開催ですので、この機会にぜひ皆様の知識向上にお役立てください。


参加申し込み : https://goo.gle/2IKUgKQ


《開催概要》

名 称:Google Cloud への移行講座
日 時:12 月 9 日 (水)12:00〜  オンライン開催
参加費:無料
プログラム:
・Google Cloud Platform とは何か
・Google Cloud Platform の基礎
・Google Cloud における仮想マシンとネットワーク
・Google Cloud におけるロギングとモニタリング
・移行元環境の評価
・Migrate for Compute Engine による Google Cloud への移行
・Qwiklabs の概要



■ お問い合わせ:
Cloud OnBoard 事務局
Email: [email protected]




Posted by Takuo Suzuki - Developer Relations Team
Share on Twitter Share on Facebook


私たちは、ユーザーのプライバシーを守るため、データアクセスにおけるユーザーコントロールと透明性を向上させる努力を重ねています。ユーザーからは一貫して、位置情報データに対する制御を強化して欲しいという声が寄せられています。そこで今年は、いくつかのプライバシーの改善策についてお知らせしました。たとえば、Google Play の位置情報アクセス許可ポリシーを改定しAndroid 11 で位置情報のアクセス許可制御を強化しました。 

バックグラウンドでの位置情報への不必要なアクセスを避けるため、改定したポリシーでは、アプリのコア機能に不可欠で、ユーザーに明らかなメリットを提供する場合に限り、アクセスが許可されます。バックグラウンド位置情報をリクエストするアプリの多くは、実際にはその情報を必要としないことがわかっています。この機能を削除するか、フォアグラウンドに変更すれば、アプリの電池効率向上に繋がりますし、位置情報を共有したくないユーザーから低評価を受けてアプリの評価が低くなることも回避できます。

バックグラウンド位置情報データを使っているアプリを Google Play に公開し続ける、または新規に公開するためには、必要情報をフォームに入力して審査を受け、2021 年 1 月 18 日までに承認を得る必要があります。ただし、2020 年 4 月 16 日より前に初公開されたアプリの手続きの期限は、2021 年 3 月 29 日となっています。 

アプリの審査を円滑に進めるためのヒント


参考情報

詳しい内容をご説明している動画(英語)Google Play Academy の無料のトレーニング コース(英語)を作成しました。アプリで必要なアップデートを行う際にぜひご確認ください。プライバシーに関するベスト プラクティス技術情報もご覧ください。コードでバックグラウンド位置情報を使っている可能性がある部分を特定する方法を確認できます。

Google Play をユーザーのプライバシーを尊重するアプリとプラットフォームを構築するため、ご理解とご協力をよろしくお願いします。


Reviewed by Konosuke Ogura -  Trust & Safety - Play & Android, Global Policy & Operations Lead and Hidenori Fujii - Google Play Developer Marketing APAC
Share on Twitter Share on Facebook

Android 開発の最新ニュースやトピックをご紹介する Now in Android。今回は連載シリーズ MAD Skills の「App Bundle」、App Bundle、AndroidX 安定版リリース、連載シリーズ Kotlin Vocabulary に関する新しい記事と動画、最近公開されたブログ記事・動画・関連ドキュメント、ポッドキャスト エピソードなどをご紹介します。


MAD Skills: App Bundle

最先端の Android 開発に関する技術コンテンツをミニシリーズごとにテーマを決めて扱う連載シリーズ MAD Skills。前回のミニシリーズ「ナビゲーション」につづいて、App Bundle を取り上げます。Wojtek KalicińskiBen Weiss が Google Play のアプリ署名、初めての App Bundle のビルド、Play Feature Delivery についてのコンテンツを公開しました。詳しくは、以下の動画と記事をご覧ください。

エピソード 1: Google Play のアプリ署名について知っておくべきこと

Android App Bundle を取り上げるミニシリーズですから、アプリの署名についてお話しするのは当然です。Google Play はユーザーのデバイスにダウンロードする APK を生成しますが、その APK をインストールするには署名が必要だからです。この動画では、Google で鍵を生成するオプションや自分の鍵をアップロードするオプションなど、Google Play Console でアプリの署名を有効化する方法について順を追って説明しています。



こちらの関連記事も忘れずにご確認ください。Play のアプリ署名についてのよくある質問を取り上げています。


エピソード 2: 初めての App Bundle のビルド

こちらの動画では、Ben が App Bundle の作成手順をご説明しています。App Bundle は Android Studio またはコマンドラインで作成し、Play Console にアップロードします。さらに、Play Console でツールを使い、アップロードしたバンドルの情報を確認する方法もお話しています。


エピソード 3: アプリで Play Feature Delivery を設定する

このエピソードでは、Android Studio を使ってアプリをモジュール化する方法のほか、インストール時(インストールするかどうかを決定するオプションの条件も指定可能)や、オンデマンドでダウンロードするモジュールを選択する方法をお話しています。さらに Ben は、API を使ってオンデマンドでモジュールのインストールをリクエストする方法も詳しく説明しています。



本エピソードは、ブログ記事(英語)でもご覧いただけます。


エピソード 4: bundletool と Play Console を使ってテストする

App Bundle を取り上げるミニシリーズ最後のエピソードでは、Wojtek がローカルでテストを行う bundletool や、Play Console を使ってアップロードしたものをテストする方法など、利用可能なツールを使ってバンドルと生成された APK をテストする方法を説明しています。



この動画でお話している内容は、いくつかの記事やドキュメントとも関連しています。ぜひ、詳しい情報をご確認ください。


App Bundle を取り上げるミニシーズ最後のコンテンツとして、2020 年 11 月 19 日(日本時間 11 月 20 日)に YouTube でリアルタイム Q&A を開催します。こちらのプレイリストに YouTube ライブへのリンクが表示されますのでご確認ください。さらに、質問を募集するツイートも行います(編集部注:セッションはすべて英語で、この日本語記事投稿時には実施済み)。


本シリーズのコンテンツアーカイブは、YouTube の MAD Skills プレイリストMedium の記事、またはすべてのリンクが掲載されているランディング ページからご覧いただけます。来週は次のミニシリーズが始まります。お楽しみに!


AndroidX

多くのアルファ版、ベータ版、RC 版の AndroidX ライブラリがリリースされました。その中には、いくつかの重要な安定版リリースもありました。最近リリースされた以下のライブラリにご注目ください。


Kotlin Vocabulary: 新しい記事と動画

前回の Now in Android #28 以降、Kotlin についていくつかの新しい記事と動画が公開されています。

クラスのデータを美しく

Florina Muntenescu が、連載シリーズ Kotlin Vocabulary に新しいエピソードを追加しました。今回のテーマは、Kotlin のデータクラスです。データクラスを使うと、ボイラープレート コードをほとんど使わずに、データを保持する構造を簡単に作成できます。しかも、equals() 関数と hashCode() 関数は、Kotlin が自動的に適切なものを生成してくれます。また、何もしなくてもクラスのプロパティの分割代入や copy() を利用できます。いつもの Kotlin Vocabulary エピソードのように、Florina がデータクラスを逆コンパイルしたバイトコードを確認し、内部の仕組みを細かくご説明しています。



組み込みデリゲート

Murat Yener が、以前に掲載した Kotlin の委譲機能についての記事続編を投稿しました(英語)。今回は、Kotlin 標準ライブラリが提供するデリゲートである lazy、observable、vetoable、notNull についてご説明しています。


Android 開発のために Kotlin を学ぶべきか?

Florina こちらの記事を投稿(英語)し、Kotlin の教育や開発に力を入れることに関して、デベロッパーの皆さんからよく寄せられるいくつかの質問にご回答しています。さらに、重要な学習関連情報へのリンクも掲載しています。


Kotlin によるクラッシュの削減と安定性の向上

この記事では、Kotlin アプリのほうが Kotlin 以外で書かれたアプリよりもエラーが起こりにくい理由について、Florina がご説明しています。その証拠となる具体的なアプリやユースケースを取り上げますが、それだけでなく、null 可能性や hashCode() != equals() など、この言語を使ったコードが安定して動作する理由についても解説しています。詳しくは、こちらのブログ記事(日本語)をご覧ください。


ADB (Android Developers Backstage) ポッドキャスト 新エピソード


前回の Now in Android 以降、Android Developers Backstage に新しいエピソードが投稿されています。以下のリンクまたはお気に入りのポッドキャスト クライアントでご確認ください。

Romain Guy Tor Norbye、そして私が、Instacart の Colin White 氏から、オープンソースのイメージ読み込みライブラリである Coil について話を聞きました。イメージの読み込み、パフォーマンス、オープンソース、そしてこの Kotlin ファーストなライブラリを Kotlin やコルーチンを使ってどう作るのかについて語り合います。


またお会いしましょう

今回は以上です。次回も Android デベロッパーの世界の最新アップデートをお届けします。お楽しみに。


Reviewed by Yuichi Araki - Developer Relations Team and Hidenori Fujii - Google Play Developer Marketing APAC

Share on Twitter Share on Facebook



12 月 9 日 から 10 日に開催する Chrome と Web についての最新情報をオンラインでお届けするカンファレンス Chrome Dev Summit 2020 で発表された内容を、日本のデベロッパーの皆さまへより詳しく日本語で解説する Chrome Dev Summit Recap 2020 の開催が決定しました。 12 月 17 日に完全オンラインで行います。




開催概要


Chrome Develper Summit 2020 で発表されたコンテンツから、日本のデベロッパー様へ向けて特にお届けしたいテーマに焦点を当て、Google 関係者や外部のエキスパートが Core Web Vitals、Web アプリ、 開発ツール/デバッグ、Trust & Safety の計 4 つのトピックスについて最新情報をご紹介します。

また、あわせてリアルタイムでお寄せいただく質問に回答する時間も設けております。ぜひこの機会にご参加ください。


日時 : 12 月 17 日(木)16:00 〜 18:30
形式 : オンラインセミナー

タイムテーブル:


  • 16:00 〜 16:05  Welcome
  • Core Web Vitals:
    • 16:05  〜 16:15 Core Web Vitals に最適化した UX パターン
    • 16:15  〜 16:30  Fireside Chat
    • 16:30  〜 16:40 Q & A
  • Web アプリ:
    • 16:40  〜 16:50  次世代のデスクトップ Web アプリ
    • 16:50  〜 17:05  Fireside Chat
    • 17:05  - 17:15  Q & A
  • 開発ツール/デバッグ: 
    • 17:15  〜 17:25  Chrome DevTools の新機能
    • 17:25  〜 17:40  Fireside Chat
    • 17:40  〜 17:50  Q & A
  • Trust & Safety:
    • 17:50  〜 18:00  プライバシーを強化して広告コンバージョンを測定するための方法
    • 18:00  〜 18:15  Fireside Chat
    • 18:15  〜 18:25  Q & A
  • 18:25  〜 18:30  Closing

※各セッションごとに Q&A の時間を設けています。登壇者、内容は変更される場合がありますので、最新情報はウェブサイトでご確認ください


参加申し込み


こちらのウェブサイトからお申し込みください。ライブ配信やアーカイブの再生・閲覧、当日の Q&A で取り上げるご質問はウェブサイトからのみ可能です。


新しい情報は、引き続き、ウェブサイトならびに本ブログでもお知らせします。 Twitter : #ChromeDevSummit



Posted by Tamao Imura - Developer Marketing Manager, Platforms and Ecosystems
Share on Twitter Share on Facebook

Google では、2020 年 12 月 9 日 (水) に 「Google Maps Platform の進化とビジネス活用ウェビナー」を開催します。 
  • 「Google Maps Platform の最新機能を知りたい」
  • 「Google Maps Platform を使うとどのようなことができるかをもっと深く知りたい」 
  • 「具体的な課題を例に Google Maps Platform の活用ノウハウを学びたい」
こうしたご要望をお持ちの皆様を対象に、今回、Google Maps Platform パートナー企業にもご協力いただき、Google Maps Platform の効果的な活用方法を深掘りします。  

また、SUUMO(スーモ)を運営される株式会社リクルート様にご登壇いただき、地図がもたらすビジネス面での具体的な価値や効果、将来展望などをお話いただきます。 以下の概要をご参照頂き、ぜひご参加ください。

《 お申し込み 》 
こちらのリンクからお申し込みください。 

※ 競合他社様からのお申し込みはお断りさせていただくことがございます。 
※ ビジネス向けのイベントとなっております。学生の方のご参加はご遠慮ください。 
※ 報道関係者のご参加はお断りさせていただきます。 


 《 開催概要 》 
名 称 : Google Maps Platform の進化とビジネス活用ウェビナー 
日 時 : 2020 年 12 月 9 日 (水) 14 : 00 - 16 : 15 
主 催 : グーグル合同会社 
プログラム : 
  • オープニング 
  • 「Google Maps Platform "最新機能" と "最新ユースケース" 徹底紹介」、グーグル合同会社 
  • パートナーセッション 
    • 「新しい時代におけるネットとリアル店舗の顧客体験」、株式会社ゴーガ 様 
    • 「Google Maps Platform × ZENRINコンテンツで物流を加速」、株式会社ゼンリンデータコム 様 
    • 「らくらく物件管理&情報共有」、国際航業株式会社 様 
  • お客様事例紹介
    • 「SUUMO(スーモ)が提供する「地図から探す、住まい探し体験」の新たな取り組み」、株式会社リクルート 様 
  • クロージング
Posted by 丸山 智康 (Tomoyasu Maruyama) - Developer Relations Engineer

Share on Twitter Share on Facebook


ユーザーは皆さんのアプリにシームレスな体験を期待しています。アプリがクラッシュすれば、低評価のレビューやアンインストールが増え、ブランドにダメージを与えてしまうでしょう。その一方で、コミュニティの皆さんとの対話の中で、Kotlin を採用する主な理由の 1 つはコードの高い安全性であるということをよく耳にします。実際に何社かのパートナーは、Kotlin を使ってコードの安定性を改善しています。この投稿では、その方法をいくつか紹介するとともに、Google Play ストアの統計結果にも注目し、Kotlin とクラッシュ数との間に相関関係があるかどうかを確認してみたいと思います。

アプリの品質

アプリの品質が影響するのは、ユーザー エクスペリエンスだけではありません。クラッシュ多いと、他のいくつかの要素にも悪影響が生じます。



Kotlin で構築したアプリはクラッシュする可能性が 20% 低い


Google Play のトップ 1,000 アプリを調査してみたところ、Kotlin を使っているアプリは、それ以外のアプリよりもユーザー 1 人あたりのクラッシュ発生率が 20% 低いことがわかりました。

その具体例として、コードの 74% が Kotlin である Swiggy のエンジニアリング チームは、新機能の開発を Kotlin に移行して以来、クラッシュを 50% 減らしました。こういった結果を Kotlin はどのように実現しているのか見ていきましょう。


NullPointerException を回避する

Google Play でのクラッシュの原因ナンバーワンは NullPointerException です。Google Home チームは、2018 年よりすべての新機能を Kotlin で書いています。その結果、1 年前と比べて null ポインタによるクラッシュが 33% 減少しました。


Google Home が NullPointerException を 33% 削減


NullPointerException を避けるには、メソッドを呼び出したりメンバーにアクセスしたりする前に、扱っているオブジェクトの参照が null でないことを確認しなければなりません。Kotlin では、null 可能性が型システムの一部として組み込まれています。たとえば、変数は最初から null 可能か null 不可能かを宣言する必要があります。null 可能性を型システムの一部として組み込むことで、コードベースについての自分の記憶や知識、またコンパイル時警告(フィールドやパラメータに @Nullable アノテーションを付けた場合)に頼る必要はなくなります。null 可能性を強制することで、単なる警告ではなく、コンパイル時にエラーが発生します。null 可能性を扱う方法については、こちらのページをご覧ください。


一般的な問題を回避する

私たちデベロッパーは、気づかないうちにアプリにたくさんの問題を紛れ込ませています。そのほとんどはあまりに軽微で、調査するのは難しいかもしれません。そのような問題のうち、Kotlin を使うことで回避できるものをいくつか紹介しましょう。


hashCode() と equals()

2 つのオブジェクトが等しい場合、それらのハッシュコードも同じである必要があります。しかし、どちらかのメソッドを実装し忘れたり、クラスに新しいプロパティを追加したときに更新し忘れてしまったりすることがよくあります。データを保持するためだけのクラスを扱う場合は、Kotlin のデータクラスを使うようにしましょう。データクラスを使うと、コンパイラが hashCode()equals() を生成してくれるので、クラスのプロパティを変更すると自動的に更新されます。


構造等価性と参照等価性

2 つのオブジェクトは構造が等しい(中身が同じ)のでしょうか。それとも、参照が等しい(ポインタが同じ)のでしょうか。Java プログラミング言語では、プリミティブには常に == を使います。そのため、実際には構造が等しいかどうかを確認(equals() を呼び出してチェック)したいのに、オブジェクトにも ==(参照が等しい)を使ってしまうというのがよくある誤りです。まず、Kotlin にはプリミティブ型はなくIntString などのクラスを使います。つまり、すべてがオブジェクトなので、オブジェクトとプリミティブ型の区別を気にする必要はありません。次に、Kotlin では == は構造が等しい、=== は参照が等しいと定義されています。したがって、誤って参照が等しいかどうかを確認してしまうことはありません。


else if else if else では十分でない場合にどうするか

enum を扱う場合、通常はすべての可能なケースを記述しなければなりません。そのため、switchif else チェーンを使うことになります。enum を修正して新しい値を追加する場合、enum を使っている各コード スニペットを手動でチェックし、新しいケースに対応しているかどうかを確認する必要があります。しかし、これはエラーにつながりがちです。Kotlin では、when を式として使うと、この確認をコンパイラに任せることができます。すべての可能な分岐に対応していない場合、コンパイラ エラーが発生します。


まとめ

ユーザーやブランドにとって、アプリの安定性は重要です。Kotlin を使い始めてクラッシュ率を減らし、ユーザーの満足度を高めてアプリの高評価を守り、ユーザーの維持や獲得につなげましょう。

詳しくは、Kotlin でより優れたアプリを作成するためにできることをお読みください。また、ケーススタディをご覧いただき、Kotlin のメリットをご確認ください。世界でデベロッパーに広く使われている言語の 1 つである Kotlin を使ってみたい方は、入門ページをご覧ください。


Reviewed by Yuichi Araki - Developer Relations Team and Nori Fujii - Google Play Developer Marketing, APAC
Share on Twitter Share on Facebook

Android 開発の最新ニュースやトピックをご紹介する Now in Android。今回は新連載シリーズ MAD Skills の「ナビゲーション」、Android X ライブラリ、連載シリーズ Kotlin Vocabulary、最近公開されたブログ記事・動画・関連ドキュメント、ポッドキャスト エピソードなどをご紹介します。


MAD Skills: ナビゲーション


新連載シリーズ MAD Skills は、Modern Android Development(最先端の Android 開発)テクノロジーの使い方をデベロッパーの皆さんにお伝えするコンテンツです。このテクノロジーを使えば、優れたアプリを簡単に作ることができます。このシリーズは、前回の Now in Android を投稿した時期に始まりました。それから数週間が経ち、Navigation コンポーネントを扱った最初のミニシリーズが完結し、リアルタイム Q&A もご用意しました。

MAD Skills の目的の 1 つは、最先端の Android 開発のさまざまな機能の使い方をお伝えするだけでなく、皆さんの問題や質問に耳を傾けて解決のお手伝いをすることでした。そのため、各ミニシリーズの終わりには、YouTube でリアルタイム Q&A を開催する予定です(編集部注:セッションはすべて英語で実施されます)。

それに向けて、Twitter で質問を募集しました。また、Twitter と YouTube でもライブで質問に回答し、さらに、プロダクトに関わっている何名かのエキスパートに、おすすめする内容について話を聞きました。

ナビゲーションについては、10 月 29 日木曜日の午前 10 時(日本時間 10 月 30 日午前 3 時)に私と Ian Lakeリアルタイム Q&A を開催し、現在はアーカイブを公開しています。寄せられたご質問は、こちらの Twitter スレッドと、#AskAndroid がついた投稿から確認できます。


ナビゲーションのエピソードを見逃してしまった方は、動画や記事で確認できます。



続きのコンテンツは、YouTube の MAD Skills プレイリストMedium の記事、またはすべてのリンクが掲載されているランディング ページからご覧いただけます。今後の MAD コンテンツにもご期待ください。11 月 1 日 からは次のシリーズが始まっています!



AndroidX

GitHub の AndroidX ライブラリ

まず、AndroidX は、 GitHub を通して多くのライブラリを提供しています。

多くのデベロッパーの皆さんは、Android でずっと使われている AOSP+Gerrit システムよりも、使い慣れた GitHub を好まれていることは認識しています。

これはすばらしいアイデアです。ただししかし、私たちが利用しているインフラストラクチャを考慮すると、そのアイデアの実現はそう簡単ではありません。それでも、皆さんの意見を踏まえて模索し始め、数か月前から Paging、Room、WorkManager という積極的に開発が行われている一部のライブラリを GitHub で利用できるようにしました。先日、Activity、Fragment、Navigation の各ライブラリも追加しましたので、ぜひご確認ください。またご自分でも貢献したいという方は、CONTRIBUTING ドキュメントに記載されている詳細をご覧ください。


安定版リリース

いつものように、たくさんのアルファ版、ベータ版、RC 版とマイナー安定版リリースがありました。主な安定版リリースについて紹介します。

MediaRouter 1.2.0: これは注目に値するバージョンです。というのも、Android 11 の新しいメディア機能のいくつかと同期する機能が追加されているからです。



Android 11 には、メディア プレーヤー用のたくさんの細かな UI が追加され、メディア コントロールが通知パネルの新しい専用の領域にまとまっているため、他の通知に紛れることなく 1 か所から簡単にメディアを制御できます。これは、新しいデベロッパー機能というより、皆さんが既に作っているかもしれない通知を別の形で表現したものです。Lollipop リリース以降で利用できる MediaSession や MediaStyle API はそのまま使うことができます。

ただし、Android 11 には、「シームレスなメディア移行」を目的としていくつかの新機能が追加されています。これにより、ユーザーは出力スイッチャー(下記)で再生デバイスを変更できます。今回の MediaRouter の新リリースを使うと、この新しいプラットフォーム機能を操作できます。


この MediaRouter の新リリースを使うと、出力スイッチャーにどの再生デバイスを表示するかを制御できるので、ユーザーはシームレスにオーディオを移動できます。

Android 11 のメディアに関する変更点を確認したい方は、Don Turner の動画 What's new in Media(メディアの新機能)をご覧ください。


アルファ版

いくつかのアルファ版リリースも紹介したいと思います。アルファ版はアルファ版であり、チームの開発が進むとともに変更が繰り返されるので、通常はアルファ版に注目することはありません。しかし、Paging と Navigation のアルファ版のリリースは、近未来のアプリ開発という点で注目に値するでしょう。


Jetpack Compose のアルファ版の開発が進んでいますが、「Jetpack Compose の世界で、[ここにお気に入りの Jetpack ライブラリを挿入] は今後どうなりますか?」と、質問を受けることがあります。

お答えします。アーキテクチャ コンポーネントの多くは、個々のビューや既存の UI ツールキットを扱うものではありません。そのため、それぞれのライブラリは、Jetpack Compose の新しい世界でどれも等しく必要かつ有用です。それだけでなく、現在私たちは、異なるコンポーネントを簡単に連携させることができるように、統合機能の開発を進めています。Compose は既に ViewModels および LiveData と組み合わせて使うことができますが、本日からは Paging Navigation の両方も Jetpack Compose のサポート対象になりました。


Kotlin Vocabulary

先日、Kotlin の言語機能に関するシリーズで 記事を 3 件公開しました。(英語記事一覧日本語記事一覧


分割代入

Florina Muntenescu が Kotlin の分割代入機能についての新しい記事(英語)と動画を投稿しました。分割代入は、オブジェクトの異なるフィールドの値を複数の変数に割り当てる際に便利です。たとえば、次のデータクラスがあったとします。


data class Donut(    dough: String,    topping: String)

すると、変数を Donut インスタンスのフィールドにすばやく割り当てることができます。


val (dough, topping) = someDonut

データクラスでは何もしなくても分割代入が動作しますが、他のクラスの関数に分割代入機能を持たせることもできます。




エクステンション

Meghan Mehta が Kotlin 言語機能のエクステンションについて説明した新しい記事(英語)を公開しました。エクステンションとは、既存のクラスに新しいメソッドやプロパティを追加できるような機能です。実際には、エクステンションが既存のクラスに何かを挿入することはありません。しかし、メソッドの呼び出し元からはそのように見えます。なお、

 内部的には、クラスのインスタンスを受け取る静的メソッドとして実装されています。


この Kotlin の機能は、私もよく使うことになりそうです。API デベロッパーとして、後から API を改善できるという考え方が気に入っています。プラットフォームやライブラリのコアの外側に API を追加するにもかかわらず、コードから使うときは、まるでそこにあるように見えるのです。たとえば、String クラスに String.isAGoodDonutName() というエクステンション メソッドを作ったとしましょう。すると、呼び出し元はこのエクステンション メソッドを使い、“Sprinkle”.isAGoodDonutName() というように String からこのメソッドを直接呼び出すことができます。他の言語のアプローチのように、他のパッケージやクラスを使って Utils.StringMethods.isAGoodDonutName(“Sprinkle”) などと記述する必要はありません。


コルーチン

最後に、Manuel Vivo が新しい動画「コルーチンの ABC」を公開し、CoroutineScopeCoroutineContextDispatcherJob などのトピックについて説明しています。コルーチンの ABC というより、CDJ のように見えるかもしれません。




その他の最近公開されたブログ記事と動画

よくある Google Play ストアのポリシー違反

アプリを公開する際に厄介なことの 1 つは、そのアプリを確実にストアのガイドラインに準拠させることです。このガイドラインは、ユーザーにとって優れたアプリのエコシステムを実現するために存在しています。しかし、正しい対処方法を厳密に伝えるのは難しい場合もあります。そこで、問題につながる可能性があるいくつかのよくある違反と、それを避ける方法についてより理解を深めていただくため、この記事を公開しました

よくあるポリシー違反の中には、アプリの UI から Play Store へのリンク、アプリの明確な概要よりも検索キーワードを意識した説明、ウェブサイトのコンテンツを WebView で見せるだけのアプリなどがあります。


カンファレンスのプレゼンテーション

多くのカンファレンスがオンラインでの開催を強いられているこの時期に、Droidcon は興味深いアプローチをとりました。たくさんのイベントを組み合わせて、広いタイムゾーンをカバーする大きなイベントを実施したのです。10 月に行われたこのカンファレンスのヨーロッパ、中東、アフリカ バージョンと、そのすべての動画がオンラインで公開されています(私たちのチームが作ったものもあれば、広大なコミュニティのとてもたくさんのデベロッパーの皆さんが作ったものもあります)。


MotionTags

スクリーンキャストの MotionTags シリーズには、前回から 2 つのエピソードが投稿されました。

MotionTags プレイリストの他のシリーズと合わせてご覧ください。




トレーニング

先日、Udacity Android Kotlin Developer Nanodegree が新しくリリースされました。このコースは、ベスト プラクティスに従って Kotlin で Android アプリを構築する方法を学びたい方が対象です。前提条件や詳しい内容は、プログラムの概要をご覧ください。

なお、この Nanodegree は有償プログラムで、フィードバック付きのプロジェクト、テクニカル メンター サポート、キャリア サービスが Udacity から提供されます。ただし、ベースとなるコースのコンテンツは Google が Udacity と共同で作成したもので、誰でも無料でアクセスできます。このコンテンツは、Kotlin による Android アプリ開発Kotlin による高度な Android で確認できます。


ADB (Android Developers Backstage) ポッドキャスト 新エピソード


前回の Now in Android 以降、Android Developers Backstage に新しいエピソードが投稿されています。以下のリンクまたはお気に入りのポッドキャスト クライアントでご確認ください。


Romain Guy と私が、新しい 3.0 バージョンPaging ライブラリ(「Paging 3」)について、Android ツールキット チームの Dustin Lam と Chris Craik に話を聞きました。


このバージョン(現在アルファ版)は、コルーチンと Flow を使って Kotlin で完全に書き直されています。それにはさまざまな理由がありますが、このポッドキャストではその点に迫っています。ぜひお聴きください。


またお会いしましょう

今回は以上です。次回も Android デベロッパーの世界の最新アップデートをお届けします。お楽しみに。


Reviewed by Takeshi Hagikura - Developer Relations Team and Hidenori Fujii - Google Play Developer Marketing APAC

Share on Twitter Share on Facebook

Google Play のアプリ掲載情報にリンクしているアプリ コンテンツの例


アプリの説明に不要な内容が含まれている

よく見られるもう 1 つの誤りは、あるキーワードやフレーズのランクを上げてアプリを見つかりやすくしようと、アプリの説明にキーワードを詰め込むことです。キーワードの繰り返しや、関係のないキーワードや参照を含むテキスト ブロックやリストは、ストアの掲載情報とプロモーションのポリシーに違反します。この違反を避ける最善の方法の 1 つは、ユーザーにとって読みやすくわかりやすいアプリの説明を書くことです。


不適切なストアの掲載情報を避ける方法や、人工的にアプリの視認性を上げる方法については、こちらの動画をご覧ください。



メンテナンスされていないアプリや動作しないアプリ


デベロッパーがかなり以前に公開し、既にメンテナンスされなくなったアプリも存在します。メンテナンスされていないアプリは、機能が動作しないなど、ユーザー エクスペリエンスの問題を生み出します。このようなアプリは、少ない星の数や否定的なユーザー レビューで評価されるリスクがあるだけでなく、最小限の機能を提供するというポリシーに違反しているとも認識される可能性があります。デベロッパーやアプリの評判が下がるのを防ぐためにも、そのようなアプリは Play Store で非公開にすることを検討してください。なお、非公開にしても、既にアプリをインストールしている既存ユーザーには影響しません。また、デベロッパーはいつでも問題を修正してアプリを再公開することができます。

メンテナンスされず動作しないアプリの例


Play アカデミーの ‘Minimum and Broken Functionality Spam’ コースを受講する


アプリか Webview か

また、既存ウェブサイトを Webview で見せているだけに過ぎないアプリもよく見かけます。こういったアプリのほとんどは、Android ユーザーにエンゲージメントの高いアプリのエクスペリエンスを提供するというよりは、単にトラフィックを上げるという目的で登録されています。このようなアプリは、Webview スパムと見なされ、Play から削除されます。アプリではウェブ以上の機能を提供することを検討し、ユーザー エクスペリエンスを高める関連機能を実装してください。


アプリの機能がない Webview の例



Play アカデミーの ‘Webview Spam’ コースを受講




ここで説明したのはよくある誤りの一部だけですが、ポリシーの最新情報については、Google Play デベロッパー ポリシー センターをご確認ください。また、最新のポリシー アップデートの詳細については、Comply with Google Play's Spam and Minimum Functionality policiesなどの Google Play アカデミーのポリシー トレーニングコースや Play PolicyBytes 動画をご覧ください。


Reviewed by Konosuke Ogura -  Trust & Safety - Play & Android, Global Policy & Operations Lead and Hidenori Fujii - Google Play Developer Marketing, APAC

Share on Twitter Share on Facebook


Kotlin Vocabulary: デフォルト引数


短くて使いやすいデフォルト引数を利用すると、ボイラープレートを書くことなく関数のオーバーロードを実現できます。多くの Kotlin の機能と同じように、この機能も魔法のように便利です。その秘密を知りたいと思いませんか?この記事では、デフォルト引数の内部の仕組みを紹介します。


基本的な使用方法


関数のオーバーロードが必要な場合、同じ関数を複数回実装する代わりに、デフォルト引数を使うことができます。


<!-- Copyright 2019 Google LLC.

   SPDX-License-Identifier: Apache-2.0 -->


// instead of:

fun play(toy: Toy){ ... }


fun play(){

    play(SqueakyToy)

}


 // use default arguments:

 fun play(toy: Toy = SqueakyToy)


fun startPlaying() {

    play(toy = Stick)

    play() // toy = SqueakyToy

}


デフォルト引数はコンストラクタにも適用できます。


<!-- Copyright 2019 Google LLC.

   SPDX-License-Identifier: Apache-2.0 -->


class Doggo(

    val name: String,

    val rating: Int = 11

)


val goodDoggo = Doggo(name = "Tofu")

val veryGoodDoggo = Doggo(name = "Tofu", rating = 12)



Java との相互利用

デフォルトでは、Java はデフォルト値のオーバーロードを認識しません。


<!-- Copyright 2019 Google LLC.

   SPDX-License-Identifier: Apache-2.0 -->

     

// kotlin

fun play(toy: Toy = SqueakyToy) {... }


// java

DoggoKt.play(DoggoKt.getSqueakyToy());

DoggoKt.play(); // error: Cannot resolve method 'play()'


コンパイラにオーバーロード メソッドを生成するよう指示するには、Kotlin 関数に @JvmOverloads アノテーションを追加します。


/* Copyright 2020 Google LLC.

   SPDX-License-Identifier: Apache-2.0 */


@JvmOverloads

fun play(toy: Toy = SqueakyToy) {… }


内部処理

コンパイラが生成した内容を確認するため、逆コンパイルした Java コードを見てみましょう。[Tools] -> [Kotlin] -> [Show Kotlin Bytecode] を選択し、[Decompile] ボタンを押します。


関数


/* Copyright 2020 Google LLC.

   SPDX-License-Identifier: Apache-2.0 */


fun play(toy: Toy = SqueakyToy)

...

fun startPlaying() {

    play(toy = Stick)

    play() // toy = SqueakyToy

}



// decompiled Java code

public static final void play(@NotNull Toy toy) {

   Intrinsics.checkNotNullParameter(toy, "toy");

}


// $FF: synthetic method

public static void play$default(Toy var0, int var1, Object var2) {

   if ((var1 & 1) != 0) {

      var0 = SqueakyToy;

   }


   play(var0);

}


public static final void startPlaying() {

   play(Stick);

   play$default((Toy)null, 1, (Object)null);

}


コンパイラが 2 つの関数を生成していることがわかります。



int パラメータ


play$default の int パラメータの値は、デフォルト引数が渡された引数の数と、そのインデックスに基づいて計算されます。Kotlin コンパイラは、どのパラメータを使って play 関数を呼び出すかを、このパラメータの値に基づいて判断します。

この例の play() の呼び出しでは、インデックス 0 の引数がデフォルト引数を使っています。そのため、int var1 = 2⁰ を使って play$default を呼び出します。


play$default((Toy)null, 1, (Object)null);


これで、play$default の実装は、var0 の値をデフォルト値で置き換えなければならないことを認識できます。


この int パラメータの動作を確認するため、もう少し複雑な例を見てみましょう。play 関数を拡張し、この関数を呼び出す際に doggotoy をデフォルト引数として使うようにします。


/* Copyright 2020 Google LLC.

   SPDX-License-Identifier: Apache-2.0 */

   

fun play(doggo: Doggo = goodDoggo, doggo2: Doggo = veryGoodDoggo, toy: Toy = SqueakyToy) {...}


fun startPlaying() {

    play2(doggo2 = myDoggo)

}


逆コンパイルしたコードはどうなったでしょうか。


/* Copyright 2020 Google LLC.

   SPDX-License-Identifier: Apache-2.0 */

   

public static final void play(@NotNull Doggo doggo, @NotNull Doggo doggo2, @NotNull Toy toy) {

...

 }


// $FF: synthetic method

public static void play$default(Doggo var0, Doggo var1, Toy var2, int var3, Object var4) {

  if ((var3 & 1) != 0) {

     var0 = goodDoggo;

  }


  if ((var3 & 2) != 0) {

     var1 = veryGoodDoggo;

  }


  if ((var3 & 4) != 0) {

     var2 = SqueakyToy;

  }


  play(var0, var1, var2);

}


public static final void startPlaying() {

    play2$default((Doggo)null, myDoggo, (Toy)null, 5, (Object)null);

 }



int パラメータが 5 になりました。この計算の仕組みは次のようになります。0 番目と 2 番目のパラメータでデフォルト引数が使われているので、var3 = 2⁰ + 2² = 5 となります。パラメータは、ビット単位の & 演算を使って次のように評価されます。



コンパイラは、var3 に適用されたビットマスクから、どのパラメータをデフォルト値と置き換えるかを計算できます。


Object パラメータ


上の例で、Object パラメータの値が常に null になっていたことに気づいたかもしれません。実際に、play$default 関数ではこの値が使われることはありません。このパラメータは、オーバーライドする関数でデフォルト値をサポートするために使用されています。


デフォルト引数と継承


デフォルト引数がある関数をオーバーライドすると、何が起きるでしょうか。

先ほどの例を次のように変更してみましょう。



PlayfulDoggo.play にデフォルト値を設定しようとしても、次のように表示され、許可されません。An overriding function is not allowed to specify default values for its parameters(オーバーライド関数では、パラメータへのデフォルト値の指定は許可されていません)


/* Copyright 2020 Google LLC.

   SPDX-License-Identifier: Apache-2.0 */


open class Doggo(

    val name: String,

    val rating: Int = 11

) {

    open fun play(toy: Toy = SqueakyToy) {...}

}


class PlayfulDoggo(val playfulness: Int, name: String, rating: Int) : Doggo(name, rating) {

    // error: An overriding function is not allowed to specify default values for its parameters

    override fun play(toy: Toy = Stick) { }

}


override を削除して逆コンパイルしたコードを確認すると、PlayfulDoggo.play() は次のようになっています。


public void play(@NotNull Toy toy) {...  }


// $FF: synthetic method

public static void play$default(Doggo var0, Toy var1, int var2, Object var3) {

  if (var3 != null) {

     throw new UnsupportedOperationException("Super calls with default arguments not supported in this target, function: play");

  } else {

     if ((var2 & 1) != 0) {

        var1 = DoggoKt.getSqueakyToy();

     }


     var0.play(var1);

  }

}


これは、デフォルト引数を使った super の呼び出しが将来的にサポートされるという意味なのでしょうか。この点については、成り行きを見守るしかありません。


コンストラクタ


コンストラクタでは、逆コンパイルした Java コードに 1 つだけ違う点があります。以下をご覧ください。


/* Copyright 2020 Google LLC.

   SPDX-License-Identifier: Apache-2.0 */

   

// kotlin declaration

class Doggo(

    val name: String,

    val rating: Int = 11

)


// decompiled Java code

public final class Doggo {

   ...


   public Doggo(@NotNull String name, int rating) {

      Intrinsics.checkNotNullParameter(name, "name");

      super();

      this.name = name;

      this.rating = rating;

   }


   // $FF: synthetic method

   public Doggo(String var1, int var2, int var3, DefaultConstructorMarker var4) {

      if ((var3 & 2) != 0) {

         var2 = 11;

      }


      this(var1, var2);

   }


コンストラクタでも合成メソッドが作成されていますが、関数で使われていた Object ではなく、DefaultConstructorMarkernull で呼び出されています。


/* Copyright 2020 Google LLC.

   SPDX-License-Identifier: Apache-2.0 */


// kotlin

val goodDoggo = Doggo("Tofu")


// decompiled Java code

Doggo goodDoggo = new Doggo("Tofu", 0, 2, (DefaultConstructorMarker)null);


デフォルト引数があるセカンダリ コンストラクタでも、プライマリ コンストラクタと同じように DefaultConstructorMarker を使った別の合成メソッドが生成されます。

/* Copyright 2020 Google LLC.

   SPDX-License-Identifier: Apache-2.0 */


// kotlin

class Doggo(

    val name: String,

    val rating: Int = 11

) {

    constructor(name: String, rating: Int, lazy: Boolean = true)    

}


// decompiled Java code

public final class Doggo {

   ...

   public Doggo(@NotNull String name, int rating) {

      ...

   }


   // $FF: synthetic method

   public Doggo(String var1, int var2, int var3, DefaultConstructorMarker var4) {

      if ((var3 & 2) != 0) {

         var2 = 11;

      }


      this(var1, var2);

   }


   public Doggo(@NotNull String name, int rating, boolean lazy) {

      ...

   }


   // $FF: synthetic method

   public Doggo(String var1, int var2, boolean var3, int var4, DefaultConstructorMarker var5) {

      if ((var4 & 4) != 0) {

         var3 = true;

      }


      this(var1, var2, var3);

   }

}


まとめ

シンプルで美しいデフォルト引数を利用すると、パラメータにデフォルト値を設定できるようになるので、メソッドをオーバーロードする際に書かなければならないボイラープレート コードの量が減ります。多くの Kotlin キーワードに言えることですが、生成されるコードを調べてみれば、そこでどのような魔法が使われているかを理解できます。詳しくは、他の Kotlin Vocabulary の投稿を確認してみてください。



Reviewed by Takeshi Hagikura - Developer Relations Team
Share on Twitter Share on Facebook


Kotlin Vocabulary: 委譲


仕事を完了する方法の 1 つは、その仕事を他者に委譲することです。皆さんの仕事を友だちに委譲することを言っているわけではありません。今回のテーマは、あるオブジェクトから別のオブジェクトに委譲することです。


ソフトウェアの世界では、委譲という考え方は新しいものではありません。委譲はデザイン パターンの 1 つで、あるオブジェクトが デリゲートと呼ばれるヘルパー オブジェクトに委譲することでリクエストを処理することを指します。デリゲートの役割は、元のオブジェクトに代わってリクエストを処理し、その結果を元のオブジェクトが利用できるようにすることです。


Kotlin はクラス委譲とプロパティ委譲をサポートしているので、委譲を簡単に扱えます。さらに、いくつかの独自の組み込みデリゲートも提供しています。

クラス委譲

最後に削除された項目を復元できる ArrayList を使うとしましょう。基本的に、必要なのは同じ ArrayList の機能だけですが、最後に削除された項目への参照が必要です。


これを実現する方法の 1 つは、ArrayList クラスを拡張することです。この新しいクラスは、MutableList インターフェースの実装ではなく ArrayList の具象クラスを拡張したものなので、ArrayList の具象クラスの実装と強く結合されることになります。


MutableList の実装で remove() 関数をオーバーライドし、削除した項目の参照を保持できるようにしたうえで、その他の空の実装を他のオブジェクトに委譲したいと思ったことはありませんか?Kotlin では、これを実現する方法が提供されています。具体的には、内部 ArrayList インスタンスに作業の大半を委譲し、その動作をカスタマイズできます。これを行うため、Kotlin には新しいキーワード by が導入されています。


では、クラス委譲の仕組みを確認してみましょう。by キーワードを使うと、Kotlin は innerList インスタンスをデリゲートとして使用するコードを自動的に生成します。


<!-- Copyright 2019 Google LLC.

SPDX-License-Identifier: Apache-2.0 -->


class ListWithTrash <T>(

   private val innerList: MutableList<T> = ArrayList<T>()

) : MutableCollection<T> by innerList {

   var deletedItem : T? = null

   override fun remove(element: T): Boolean {

       deletedItem = element

       return innerList.remove(element)

   }

   fun recover(): T? {

       return deletedItem

   }

}


by キーワードは、MutableList インターフェースの機能を innerList という名前の内部 ArrayList インスタンスに委譲するよう Kotlin に伝えます。内部 ArrayList オブジェクトに直接橋渡しするメソッドが提供されるので、ListWithTrashMutableList インターフェースのすべての機能をサポートします。さらに、独自の動作を追加することもできるようになります。

内部処理

動作の仕組みを確認してみましょう。ListWithTrash のバイトコードを逆コンパイルした Java コードを見ると、Kotlin コンパイラが実際にラッパー関数を作成していることを確認できます。このラッパー関数が、内部 ArrayList オブジェクトの対応する関数を呼び出していることもわかります。


public final class ListWithTrash implements Collection, KMutableCollection {

  @Nullable

  private Object deletedItem;

  private final List innerList;


  @Nullable

  public final Object getDeletedItem() {

     return this.deletedItem;

  }


  public final void setDeletedItem(@Nullable Object var1) {

     this.deletedItem = var1;

  }


  public boolean remove(Object element) {

     this.deletedItem = element;

     return this.innerList.remove(element);

  }


  @Nullable

  public final Object recover() {

     return this.deletedItem;

  }


  public ListWithTrash() {

     this((List)null, 1, (DefaultConstructorMarker)null);

  }


  public int getSize() {

     return this.innerList.size();

  }


  // $FF: bridge method

  public final int size() {

     return this.getSize();

  }

  //...and so on

}


注: 生成されたコードで、Kotlin コンパイラは Decorator パターンという別のデザイン パターンを使ってクラス委譲をサポートしています。Decorator パターンでは、デコレータ クラスがデコレートされるクラスと同じインターフェースを共有します。デコレータ クラスは、ターゲット クラスの内部参照を保持し、そのインターフェースで提供されるすべてのパブリック メソッドをラップ(デコレート)します。


委譲は、特定のクラスを継承できない場合に特に便利です。クラス委譲を使うと、クラスが他のクラスの階層に含まれることはなくなります。その代わり、同じインターフェースを共有し、元の型の内部オブジェクトをデコレートします。つまり、パブリック API を維持したまま、実装を簡単に入れ替えることができます。

プロパティ委譲

by キーワードを使うと、クラス委譲だけでなく、プロパティを委譲することもできます。プロパティ委譲では、デリゲートはプロパティの get 関数と set 関数の呼び出しを担当します。他のオブジェクトで getter/setter ロジックを再利用しなければならない場合、対応するフィールドだけでなく機能を簡単に拡張することができるので、この機能が非常に便利です。


次のような定義の Person クラスがあったとしましょう。


class Person(var name:String, var lastname:String)


このクラスの name プロパティには、いくつかのフォーマット要件があります。name を設定するとき、先頭の文字が大文字、他の文字が小文字になるようにします。さらに、 name を更新する場合、updateCount プロパティを自動的にインクリメントします。

この機能は、次のように実装してもいいかもしれません 。


<!-- Copyright 2019 Google LLC.

SPDX-License-Identifier: Apache-2.0 -->


class Person(name: String, var lastname: String) {

   var name: String = name

       set(value) {

           field = value.toLowerCase().capitalize()

           updateCount++

       }

   var updateCount = 0

}


これは動作しますが、要件が変わって lastname が変更されたときも updateCount をインクリメントすることになるとどうでしょうか。ロジックをコピーして貼り付け、カスタムの setter を書いてもいいかもしれませんが、両方のプロパティにまったく同じ setter を書いていることに気づくでしょう。


<!-- Copyright 2019 Google LLC.

SPDX-License-Identifier: Apache-2.0 -->


class Person(name: String, lastname: String) {

   var name: String = name

       set(value) {

           field = value.toLowerCase().capitalize()

           updateCount++

       }

   var lastname: String = lastname

       set(value) {

           field = value.toLowerCase().capitalize()

           updateCount++

       }

   var updateCount = 0

}


どちらの setter メソッドもほぼ同じということは、どちらかは不要ということです。プロパティ委譲を使うと、getter と setter をプロパティに委譲してコードを再利用できます。

クラス委譲と同じように、by を使ってプロパティを委譲します。すると、プロパティ構文を使ったときに、Kotlin はデリゲートを使うコードを生成します。


<!-- Copyright 2019 Google LLC.

SPDX-License-Identifier: Apache-2.0 -->


class Person(name: String, lastname: String) {

   var name: String by FormatDelegate()

   var lastname: String by FormatDelegate()

   var updateCount = 0

}


この変更を行うと、name プロパティと lastname プロパティが FormatDelegate クラスに委譲されます。FormatDelegate のコードを確認してみましょう。デリゲート クラスは、getter だけを委譲する場合は ReadProperty<Any?, String> を、getter と setter の両方を委譲する場合は ReadWriteProperty<Any?, String> を実装する必要があります。この例の FormatDelegate は、setter が呼び出された場合にフォーマット処理を行うので、ReadWriteProperty<Any?, String> を実装しなければなりません。


<!-- Copyright 2019 Google LLC.

SPDX-License-Identifier: Apache-2.0 -->


class FormatDelegate : ReadWriteProperty<Any?, String> {

   private var formattedString: String = ""


   override fun getValue(

       thisRef: Any?,

       property: KProperty<*>

   ): String {

       return formattedString

   }


   override fun setValue(

       thisRef: Any?,

       property: KProperty<*>,

       value: String

   ) {

       formattedString = value.toLowerCase().capitalize()

   }

}


getter 関数と setter 関数に 2 つの追加パラメータがあることに気づいた方もいらっしゃるでしょう。最初のパラメータ thisRef は、プロパティを含むオブジェクトを表します。これを使うと、オブジェクト自体にアクセスし、他のプロパティを確認したり、他のクラス関数を呼び出したりできます。2 つ目のパラメータは KProperty<*> です。これは、委譲されたプロパティについてのメタデータにアクセスするために使うことができます。

先ほどの要件を思い出してみてください。thisRef を使って updateCount プロパティにアクセスし、インクリメントしてみましょう。


<!-- Copyright 2019 Google LLC.

SPDX-License-Identifier: Apache-2.0 -->


override fun setValue(

   thisRef: Any?,

   property: KProperty<*>,

   value: String

) {

   if (thisRef is Person) {

       thisRef.updateCount++

   }

   formattedString = value.toLowerCase().capitalize()

}


内部処理

この仕組みを理解するため、逆コンパイルした Java コードを見てみます。Kotlin コンパイラは、name プロパティと lastname プロパティについての FormatDelegate オブジェクトへのプライベートな参照を保持するためのコードと、追加したロジックを含む getter/setter の両方を生成します。

さらに、委譲されるプロパティを保持する KProperty[] も作成しています。name プロパティに対して生成された getter と setter を見てみると、インスタンスはインデックス 0 に保存されています。一方、lastname プロパティはインデックス 1 に保存されています。


public final class Person {

  // $FF: synthetic field

  static final KProperty[] $$delegatedProperties = new KProperty[]{(KProperty)Reflection.mutableProperty1(new MutablePropertyReference1Impl(Reflection.getOrCreateKotlinClass(Person.class), "name", "getName()Ljava/lang/String;")), (KProperty)Reflection.mutableProperty1(new MutablePropertyReference1Impl(Reflection.getOrCreateKotlinClass(Person.class), "lastname", "getlastname()Ljava/lang/String;"))};

  @NotNull

  private final FormatDelegate name$delegate;

  @NotNull

  private final FormatDelegate lastname$delegate;

  private int updateCount;


  @NotNull

  public final String getName() {

     return this.name$delegate.getValue(this, $$delegatedProperties[0]);

  }


  public final void setName(@NotNull String var1) {

     Intrinsics.checkParameterIsNotNull(var1, "<set-?>");

     this.name$delegate.setValue(this, $$delegatedProperties[0], var1);

  }

  //...

}


この仕組みによって、通常のプロパティ構文を使って任意の呼び出し元が委譲されるプロパティにアクセスできるようになっています。


person.lastname = “Smith” //

println(“Update count is $person.count”)


Kotlin は単に委譲をサポートしているだけではありません。Kotlin 標準ライブラリで組み込みの委譲も提供していますが、詳しくは別の記事で説明したいと思います。

委譲は他のオブジェクトにタスクを委譲する際に役立ち、コードの再利用性を高めます。Kotlin コンパイラは、委譲をシームレスに使えるようにコードを作成します。Kotlin は、by キーワードを使ったシンプルな構文でプロパティやクラスの委譲を行います。Kotlin コンパイラは、パブリック API を一切変更せず、委譲をサポートするために必要なすべてのコードを内部的に生成します。簡単に言えば、Kotlin は委譲に必要なボイラープレート コードをすべて生成して維持してくれます。つまり、委譲を Kotlin に委譲することができるのです。


Reviewed by Yuichi Araki - Developer Relations Team


Share on Twitter Share on Facebook




不正なサイトでの邪魔にならない通知のモバイル UI。新しい UI により、ユーザーはこのようなサイトからの通知を許可しにくくなっている。
この UI は、以前に Chrome 84 でお知らせした UI とまったく同じです。Chrome 86 での唯一の違いは、不正な通知コンテンツを送るパターンが検出されているサイトで、通知許可リクエストのブロックが始まることです。

これを行う理由は何ですか?

不正な通知プロンプトは、Chrome に関してユーザーから特に多く寄せられる苦情の 1 つです。今回の変更の目的は、Chrome のユーザー エクスペリエンスを向上させ、不正なサイトがウェブ通知機能を悪用しようとする動機を減らすことにあります。

Chrome はどのようにして不正な通知コンテンツを送信するサイトを検出するのですか?

Google の自動ウェブ クロール サービスは、ウェブサイトからプッシュ通知の許可がリクエストされると、ときどきプッシュ通知をサブスクライブします。自動 Chrome インスタンスに送信された通知は、セーフ ブラウジング テクノロジーを使って不正なコンテンツかどうかを評価します。問題が解決されない場合は、不正な通知を送信するサイトにフラグを付け、制限の対象にします。

自分のウェブサイトから不正な通知が検出された場合、どうなりますか?

何らかの不正な通知と見なされてサイトが「失敗」ステータスになると、Search Console は登録されているサイト運営者やサイトの Search Console ユーザーにメールで通知します。これは、少なくとも制限が開始される 30 日前(暦日)に行われます。ウェブサイトは、30 日の猶予期間内に、問題に対処して再審査をリクエストできます。

懸念があるサイト運営者やデベロッパーの方には、Search Console の Abusive Notifications Report を確認することをお勧めします。Search Console のヘルプセンターにも、Abusive Notifications Report不正な通知の審査プロセスについての追加情報が掲載されています。

自分のサイトが不正な通知の審査に通らなかった場合、どうすればよいですか?

Search Console のヘルプセンターには、不正な通知を修正し、再度ウェブサイトの審査をリクエストする方法を説明したガイドが掲載されています。

不正な通知からの保護について他に計画していることはありますか?

多くのユーザーは、Chrome の不正な通知からの保護がリリースされる前に、既に悪質なウェブサイトからの通知を意図せずに許可しています。 Chrome の今後のリリースでは、不正なオリジンからの通知許可ステータスを「許可」から「デフォルト」に戻す対策を行う予定です。これにより、ユーザーが不正なオリジンに戻って通知を再度有効にしない限り、通知が行われなくなります。

私たちは、現在の制限の効果に関して、ユーザーやデベロッパーからのフィードバックに耳を傾けています。そのフィードバックに基づいてさらに変更を行う可能性があります。

Reviewed by Eiji Kitamura - Developer Relations Team
Share on Twitter Share on Facebook