ユーザーの端末の保護
Play プロテクトは、少なくとも 1 日に 1 回、自動的に Android 端末を確認して PHA を探します。ユーザーは、いつでも追加の確認を行うこともできます。昨年は、この自動確認機能によって、約 3,900 万件の PHA を削除することができました。

さらに、Android エコシステム全体で新たに検知した PHA のトレンドに対応できるよう、Play プロテクトを継続的にアップデートしています。たとえば、新しい PHA のインストールのうち 35% 近くが、端末がオフライン、つまりネットワークに接続されていない間に起きていることが判明したことを受けて、2017 年 10 月に Play プロテクトにオフライン スキャン機能を導入しました。それ以来、1,000 万件以上の PHA インストールを阻止しています。

PHA のダウンロードを阻止
Google Play だけからアプリをダウンロードしている端末は、他のアプリ配信元からアプリをダウンロードしている端末に比べ、PHA が含まれる確率はたったの 9 分の 1 です。そして、このセキュリティ保護機能はさらに向上し続けています。Play に新しくアップロードされるアプリに対する Play プロテクトの検査機能が強化されていることもその一因です。昨年、Play プロテクトが確認を行った Play アプリは、2016 年に比べて 65% 増加しました。

Play プロテクトは、ただ Google Play のユーザーを保護しているだけではなく、より広範な Android エコシステムも保護しています。昨年、Google Play 以外からの PHA のインストール率も 60% 以上低下しましたが、その低下の大部分は Play プロテクトによるものでした。

セキュリティ アップデート


Google Play プロテクトは、有害な PHA に対する強力な盾です。同時に、ユーザーの端末で動作している Android のバージョンがより確実に最新かつ安全なものになるように、端末メーカーと協力した取り組みも行っています。

そうした取り組みの一環として、昨年を通して、セキュリティ アップデートをリリースするプロセスの改善を行いました。このため、昨年セキュリティ パッチを受信した端末は 2016 年と比べて 30% 以上増加しました。さらに、Android 端末で利用できるアップデートや緩和策がないまま、Android プラットフォームに影響する重大なセキュリティ脆弱性が一般公開に至るというケースはありませんでした。これを可能にしたのが、Android Security Rewards Programセキュリティ研究者コミュニティとの協力関係の強化、業界の各パートナーとの連携、そして Android プラットフォームに本来備わっているセキュリティ機能です。

Android Oreo の新しいセキュリティ機能


Android Oreo には、たくさんの新しいセキュリティ機能が導入されています。具体的には、より安全なアプリのインストール機能安全でないネットワーク プロトコルの削除、端末識別子の利用についての制限の強化、カーネルの強化などです。

これらの機能の多くは、昨年を通して随時紹介してきましたが、これまで紹介できなかった機能もあるかもしれません。たとえば、画面全体をブロックして解除できなくすることを不可能にするため、画面にオーバーレイ表示する API をアップデートしました。画面全体をブロックするという手法は、ランサムウェアでよく使われていました。

オープン性がもたらす Android の強固なセキュリティ


これは私たちが昔から言い続けてきたことですが、いつにも増して真実性を増しています。すなわち、Android のオープン性は、セキュリティ保護の強化に貢献しています。Android のエコシステムは何年にもわたって研究者の皆さんの発見からメリットを受けており、2017 年も例外ではありませんでした。

セキュリティ褒賞金プログラム
昨年も Android Security Rewards プログラムは、引き続き大きな成果をもたらしました。研究者の皆さんに支払われた報奨金は 128 万ドルにのぼり、このプログラムが始まってから支払われた合計金額は 200 万ドルを超えました。また、支払い上限額を変更し、TrustZone とセキュアブートの欠陥発見に対する報奨金の上限を5 万ドルから 20 万ドルに、リモート カーネルの欠陥発見に対しては 3 万ドルから 15 万ドルに増額されました。

併せて、Google Play Security Rewards Program を導入しています。これは、Play に公開されているアプリで一部の重要な脆弱性を発見し、それを開発元に開示したデベロッパーに対して報奨金を提供するものです。

外部のセキュリティ コンテスト
私たちのチームは、Mobile Pwn2Own などの脆弱性を見つけて開示するコンテストにも参加しています。2017 年の Mobile Pwn2Own コンテストでは、Google Pixel の欠陥を見つけることができた参加者はいませんでした。また、Android を実行している端末の欠陥がデモ紹介されましたが、Android オープンソース プロジェクト(AOSP)内の改変されていない Android ソースコードを実行している端末では、それらの欠陥はどれも再現されませんでした。

Android セキュリティについて、このような前向きな動向が続いていることを嬉しく思っています。今年以降も、こういった保護機能を改善する取り組みを継続していきます。Android ユーザーの安全を守るため、私たちは決して立ち止まることなく取り組み続けていきたいと考えています。


Reviewed by Ryosuke Matsuuchi - Developer Relations Team


本日(*原文公開当時)は、Android Emulator のクイックブートについてお知らせします。クイックブートを使うと、Android Emulator を 6 秒未満で起動できます。エミュレータのセッションのスナップショットを使って実現しているので、数秒で再読み込みできます。クイックブートは、Android Studio 3.0 の Canary アップデート チャンネルで初めてリリースされましたが、本日(*原文公開当時)、安定版アップデートとしてリリースされました。

この新機能に加えて、最近のリリースの主な機能をいくつかご紹介します。私たちは、2 年前に Android Emulator を完全に再構築してから、スピードや安定性の改善を行ったり、アプリの開発やテストを高速化する豊富な新機能を追加することに注力してきました。これらの直近の変更は、すぐに最新バージョンの Android Emulator にアップデートして使い始めるだけの価値が十分あるものです。

主な 5 つの機能
  • クイックブート - クイックブートは、本日安定版機能としてリリースされました。これを使うと、Android Emulator セッションを 6 秒未満で再開できます。最初に Android Emulator で Android Virtual Device(AVD)を起動するときはコールドブート(端末の電源を入れるのと同じような処理)を行う必要がありますが、それ以降は高速に起動し、システムが最後にエミュレータを閉じたときの状態に復元されます(端末のスリープを解除するのと同じような処理)。これは、以前のエミュレータのスナップショット アーキテクチャを完全に再設計し、仮想センサーや GPU アクセラレーションと連携させることで実現しています。Android Emulator v27.0.2 以降では、クイックブートがデフォルトで有効になっているので、追加の設定は必要ありません。


Android Emulator のクイックブート


  • Android CTS 対応 - Android Emulator は、Android SDK がリリースされるたびに、Android KitKat との下位互換性のテストからデベロッパー プレビューの最新 API の組み込みまで、確実にアプリ開発のニーズに対応できるようになっています。製品の品質とエミュレータ システム イメージの信頼性向上のため、Android Nougat(API 24)以降の最終の Android System Image ビルドは、公式の Android 物理端末が合格する必要があるテストスイートである Android Compatibility Test Suite(CTS)を使った検査が行われています。
  • Google Play サポート - 多くのアプリ デベロッパーが Google Play Services を使っていることや、Android Emulator システム イメージでこのサービスを最新版に保つのは難しい場合があることは認識しています。この問題を解決するために、現在は Play Store アプリを含む Android System Image を提供しています。Google Play イメージは、Android Nougat(API 24)以降で利用できます。この新しいエミュレータ イメージを使うと、物理 Android 端末と同じように、エミュレータから Play Store アプリ経由で Google Play Services をアップデートできます。さらに、Google Play Store を使ってインストール、アップデート、購入のフローを包括的にテストできます。
  • パフォーマンスの改善 - 高速でパフォーマンスの高いエミュレータを作成することは、私たちのチームの継続的な目標です。開発マシンでエミュレータを実行する際のパフォーマンスの影響、特に RAM の使用量には継続的に注目しています。最新バージョンの Android Emulator では、AVD で定義されている最大 RAM サイズのメモリを固定的に割り当てるのではなく、オンデマンドで RAM を割り当てるようになっています。これは、Linux(KVM)および macOS® (Hypervisor.Framework)ではネイティブ ハイパーバイザ、Microsoft® Windows® では新しいオンデマンド メモリ割り当てを活用する拡張 Intel®HAXM(v6.2.1 以降)を活用して実現しています。

  • さらに、ここ数回のリリースで、CPU と I/O のパフォーマンスを改善するとともに、OpenGL ES 3.0 サポートなどで GPU の活用によるパフォーマンスの強化も行っています。ADB プッシュなどの一般的なタスクでの Android の CPU と I/O パイプラインの改善の成果をご覧ください。


    Android Emulator との ADB Push のスピード比較



    GPU パフォーマンスについては、時間的な改善を計測できるように、サンプルの GPU エミュレーション負荷テストアプリを作成しています。最新のエミュレータは、以前より高いフレームレートでレンダリングできることがわかりました。また、Android Emulator は、Android 仕様に従って OpenGL ES 3.0 を正確にレンダリングできる数少ないエミュレータのひとつです。


GPU エミュレーション負荷テスト - Android アプリ




Android Emulator での GPU エミュレーション負荷テスト



その他の機能

以上で紹介した主な機能のほか、この 1 年で多くの機能が Android Emulator に追加されました。中には、皆さんが気づいていないものもあるかもしれません。
  • Wi-Fi サポート - API 24 システム イメージ以降では、仮想セルラー ネットワーク用と仮想 Wi-Fi アクセス ポイントの両方に接続できる AVD を作成できます。
  • Google Cast サポート - Google Play システム イメージを使うと、同じ Wi-Fi ネットワーク上にある Chromecast 端末に画面やオーディオ コンテンツをキャストできます。
  • APK やファイルのドラッグ&ドロップ - APK を Android Emulator ウィンドウにドラッグするだけで、アプリをインストールできます。また、他のデータファイルをドラッグすると、Android Virtual Device の /Downloads フォルダに格納されます。
  • ホストからのコピーと貼り付け - Android Emulator と開発マシン間でテキストをコピーして貼り付けることができます。
  • 2 本指での仮想ピンチと仮想ズーム - Google マップなどのアプリを操作するときは、Ctrl キー(Microsoft® Windows® または Linux の場合)または ⌘(macOS® の場合)を押すと、画面に指が表示され、ピンチ操作やズーム操作を行うことができます。
  • GPS 位置情報 - Android Emulator の [Location] タブから、手動で GPS ポイントの選択や設定を行うことができます。
  • 仮想センサー - 拡張コントロール パネルに専用のページがあり、Android Emulator でサポートされている加速度センサー、回転センサー、近接センサーなどのさまざまなセンサーが表示されます。
  • WebCam サポート - ウェブカメラやノートパソコンに組み込まれているカメラを AVD の仮想カメラとして使うことができます。AVD Manager の [Advanced Settings] ページで AVD カメラ設定を確認してください。
  • ホストマシンのキーボード - 実際のキーボードを使って Android Virtual Device にテキストを入力することができます。
  • 仮想 SMS と仮想通話 - 拡張コントロール パネルで仮想 SMS または仮想通話を起動すると、電話の機能に依存するアプリをテストすることができます。
  • 画面ズーム - メイン ツールバーで拡大鏡アイコンをクリックしてズームモードを開始して、調べたい画面の範囲を選択します。
  • ウィンドウのサイズ変更 - Android Emulator ウィンドウの端をドラッグすると、希望のサイズに変更できます。
  • ネットワーク プロキシ サポート - [Proxy] タブの [Settings] ページから Android Emulator セッションにカスタム HTTP プロキシを追加できます。
  • バグレポート - 拡張コントロール パネルの [Bug Report] セクションから、アプリのバグレポートをすばやく作成し、チームで共有したり、Google にフィードバックを送ったりできます。

Android Emulator の詳細については、エミュレータのドキュメントをご覧ください。

スタート ガイド

ここで説明したすべての機能や改善点は、Android Emulator v27.0.2 以降をダウンロードすると利用できます。これは、Android Studio の SDK Manager から取得できます。高速に利用するために、最新の Android Emulator、Intel® HAXM(該当する場合)、グラフィック ドライバーをインストールし、x86 版のエミュレータ システム イメージを作成して実行することをお勧めします。

気に入った機能や問題点、新機能の提案などのフィードバックは大歓迎です。バグや問題を見つけた方や、機能リクエストがある方は、ご遠慮なく問題を送信してください。もちろん、まだ完璧ではありませんが、ここまでの改善を喜んでいただけることを期待しています。



Reviewed by Takeshi Hagikura - Developer Relations Team


Googleでは、ウェブをよりよくすることを目的としたオープンソースの取り組み、Accelerated Mobile Pages (AMP)プロジェクトを率いる AMP チームのメンバーを招き、インタラクティブでレスポンシブなサイトを開発・収益化する方法を学ぶ「AMP Roadshow Tokyo」を開催します。

AMP DevRel チームの Paul Bakaus をはじめ、各地から AMP チームメンバーが来日し、今年の 2 月にアムステルダムで行われた AMP Conference 2018 のトピックの中から、主に AMP の新しい機能に関する情報を同時通訳付きでお届けします。東京オフィスで AMP を担当しているメンバーもスピーカーとしてセッションを行う予定です。


イベント概要


イベント名: AMP Roadshow Tokyo
日程: 2018 年 4 月 27 日(金) 9:30 - 17:00(開場: 9:00)
場所:グーグル合同会社
定員 :240 名


タイムテーブル


9:00am 開場
9:30am ご挨拶と基調講演
9:45am Rich content experiences with AMP
10:15am Advanced interactivity with AMP
10:45am 休憩
11:00am Progressive Web AMPs
11:30am AMP in production
12:00pm What's next in AMP
12:30pm ランチ
1:30pm Guest Talk or Panel
2:00pm Q&A with AMP team
2:30pm Monetization with AMP
3:00pm Amplify live!
5:00pm まとめ


申込方法


本イベントへの申し込み、詳細につきましてはこちらのサイトをご覧ください。
※ 参加可能な方には、後日参加証を送付いたします。


Posted by Takuo Suzuki - Developer Relations Team


ゲームに合わせて自由にカスタマイズ

皆さんに簡単にお使い頂けるように、Google マップの持つ豊富なデータを Unity ゲームエンジンから利用できるようにしました。ビルや道路、公園が Unity の GameObject になるので、テクスチャやスタイルを追加してカスタマイズし、ゲームにぴったりの世界観を実現できます。また、現実世界のデータを構築する手間が省けるので、ゲームデベロッパーは、表現力豊かで迫力のあるゲーム体験を作成することに集中できるでしょう。

「Google マップのデータを Unity に組み込んで使えるので、ユーザーが現実世界でバーチャルな恐竜を見つけるという仮想体験の構築に本来の時間と労力を集中させることができました。」 - Ludia の CEO、Alexandre Thabet 氏


世界中のあらゆる場所で迫力満点の体験を

ゲーム デベロッパーは、詳細で正確な生きた世界のモデルにアクセスし、それらを使ってゲームの世界の土台を作ることができます。200 か国、1 億以上の 3D のビル、道路、建造物、公園などにアクセスできるので、地球上のあらゆる場所を使って質の高い魅力的なゲームを作ることができます。

「Google と協力することで、最新かつ高品質のロケーション データを活用し、位置情報と結びついた迫力満点の体験をゲームで実現できることにとても興奮しています。新しいビルや道路が作られると、ゲームの中でもそれらにアクセスすることができます。Google マップのロケーション データにかなうものはありません。自由の女神、エッフェル塔、ロンドンアイ、ブルジュ ハリファ、インド門など、世界の有名な建造物や企業、ビルを網羅しているので、周辺の探索も息をのむような体験に変わります」 - Next Games の CEO、Teemu Huuhtanen 氏


現実世界を使って質の高い魅力的なゲームをデザイン

世界規模で現実世界の場所と連動するゲームを設計するというのは、難しい挑戦です。しかも、プレイヤーの環境についてたくさんのことを知る必要があります。そこで、プレイヤーの居場所に関係なく、快適で楽しく何の問題もなくプレーできる場所を簡単に見つけることができるようになっています。

「現実世界の場所と連動するゲームを世界規模で構築するのは、難しいことです。ユーザーと関連があり、かつ楽しくプレーできる場所を見つけるのも同様です。ユーザーと関連がある現実世界をゲームに組み込む際に、とても役に立ったのが Google Maps API です。Google のロケーション データを活用することによって、世界中のユーザーが私たちのゲームを通してゴーストバスターズの仮想世界を体験できるようになりました」 - FourThirtyThree Inc.(4:33) の CEO、HAN Sung Gin


Google のインフラが提供する新たなゲーム体験

Google マップのグローバル インフラを活用しているということは、応答時間が早く、オンデマンドで拡張できるということです。さらに、ゲームが確実に動作するという安心を得ることもできます。

Google の優れたプロダクトをモバイルゲームにもご活用ください。早期アクセス パートナーは、ユーザーの環境を詳細に理解するために、ARCore を利用しました。これによって、エコシステム全体の 1 億台以上の端末を対象にすることができています。Google は、ゲームサーバーとして利用できる Google Cloud から、プロモーションに役立つ YouTube や Google Play まで、デベロッパーをサポートするさまざまなプロダクトがあります。

現実世界を使ったゲーム体験を構築してみたいと思っている方は、ウェブページ(英語)にアクセスするか、営業担当にご連絡ください。


Reviewed by 丸山 智康 (Tomoyasu Maruyama) - Google Customer Engineering Lead, Japan and APAC
Share on Twitter Share on Facebook


また、DataSnapshot から読み取り、いくつかの TextView にコピーするコードは次のようになっています。
// update the UI with values from the snapshot
String ticker = dataSnapshot.child("ticker").getValue(String.class);
tvTicker.setText(ticker);
Float price = dataSnapshot.child("price").getValue(Float.class);
tvPrice.setText(String.format(Locale.getDefault(), "%.2f", price));

Realtime Database SDK を使うと、実に簡単に DataSnapshot を JavaBean スタイルのオブジェクトに変換できます。最初に行う必要があるのは、スナップショットのフィールド名に一致する getter と setter を持つ Bean クラスを定義することです。
public class HotStock {
    private String ticker;
    private float price;

    public String getTicker() {
        return ticker;
    }

    public void setTicker(String ticker) {
        this.ticker = ticker;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public String toString() {
        return "{HotStock ticker=" + ticker + " price=" + price + "}";
    }
}

次に、SDK を呼び出して、自動マッピングを行います。
HotStock stock = dataSnapshot.getValue(HotStock.class)

この行が実行されると、tickerprice の値を含む HotStock の新しいインスタンスが作成されます。この便利な行を使うと、HotStockViewModel の実装を更新してこの変換を行うことができます。この変換によって、LiveData オブジェクトを作成できます。これは、入力される DataSnapshot を自動的に HotStock に変換します。この変換は、Function オブジェクトの中で行います。具体的には、ViewModel 内で次のようにして構築することができます。
// This is a LiveData<DataSnapshot> from part 1
private final FirebaseQueryLiveData liveData = new FirebaseQueryLiveData(HOT_STOCK_REF);

private final LiveData<HotStock> hotStockLiveData =
    Transformations.map(liveData, new Deserializer());

private class Deserializer implements Function<DataSnapshot, HotStock> {
    @Override
    public HotStock apply(DataSnapshot dataSnapshot) {
        return dataSnapshot.getValue(HotStock.class);
    }
}

@NonNull
public LiveData<HotStock> getHotStockLiveData() {
    return hotStockLiveData;
}

ユーティリティ クラス Transformations には、静的メソッド map() があります。ソースとなる LiveData オブジェクトと Function の実装をこのメソッドに渡すと、新しい LiveData オブジェクトが返されます。この新しい LiveData は、ソースから取得したすべてのオブジェクトに Function を適用し、その Function の出力を返します。Deserializer 関数は、入力型 DataSnapshot と出力型 HotStock というパラメータを持っています。これは、DataSnapshot をデシリアライズして HotStock を生成するという単純な仕事をしています。最後に、LiveData に変換されたこの新しい HotStock オブジェクトを返す getter を追加します。

これを追加することによって、アプリケーションのコードは DataSnapshot オブジェクトと HotStock オブジェクトのどちらの更新を受け取ることも選択できるようになります。ベスト プラクティスとしては、ViewModel オブジェクトは、UI コンポーネントがデータを処理しなくてもいいように、そのままデータを表示できる状態のオブジェクトを返すべきです。つまり、UI レイヤーで必要となる前処理は、すべて HotStockViewModel が行わなくてはなりません。これは当然、今回のケースにも当てはまります。HotStock は、いつでも UI を設定する Activity で利用可能な状態になっているからです。この時点で、Activity 全体は次のようになります。
public class MainActivity extends AppCompatActivity {

    private TextView tvTicker;
    private TextView tvPrice;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvTicker = findViewById(R.id.ticker);
        tvPrice = findViewById(R.id.price);

        HotStockViewModel hotStockViewModel = 
           ViewModelProviders.of(this).get(HotStockViewModel.class);
        LiveData<HotStock> hotStockLiveData = 
           hotStockViewModel.getHotStockLiveData();
        hotStockLiveData.observe(this, new Observer() {
           @Override
            public void onChanged(@Nullable HotStock hotStock) {
               if (hotStock != null) {
                  // update the UI here with values in the snapshot
                  tvTicker.setText(hotStock.getTicker());
                  tvPrice.setText(String.format(Locale.getDefault(), "%.2f",
                     hotStock.getPrice()));
               }
        });
    }
}


Realtime Database オブジェクトへの参照はすべてなくなり、HotStockViewModelLiveData で抽象化されています!しかし、まだ問題になる可能性があることが 1 つ残されています。

LiveData への変換の負荷が大きい場合


LiveDataonChanged() に対するコールバックは、すべてメインスレッドで実行されます。同じように、変換もメインスレッドで行われます。ここで示した例は小さく単純なものなので、パフォーマンスが問題になることはないでしょう。しかし、Realtime Database SDK が DataSnapshot を JavaBean タイプのオブジェクトにデシリアライズする際には、リフレクションを使って Bean に値を設定する setter メソッドを動的に検索して呼び出しています。オブジェクトの量やサイズが大きくなると、この処理に大量の計算が必要になります。変換に必要な合計時間が 16ms(メインスレッド上の作業単位に対して使える時間)を超える場合、Android でフレーム落ちが発生するようになります。フレーム落ちが発生すると、なめらかな 60fps でレンダリングできず、UI の動作はぎこちなくなります。これが「ジャンク」と呼ばれる現象です。ジャンクが起きると、質の悪いアプリに見えます。さらに悪いことに、データの変換に何らかの I/O が必要となる場合、アプリが無応答になって ANR が発生する場合もあります。

変換の負荷が大きくなることが心配な方は、計算処理を別のスレッドに移すべきでしょう。これは、変換処理の中で行うことはできませんが(同期的に実行されるため)、MediatorLiveData と呼ばれる仕組みを使うことができます。MediatorLiveData は、map 変換上に構築されている仕組みで、別の LiveData ソースの変更を監視して、それぞれのイベントにどのように反応するかを指定することができます。では、既存の変換を置き換えて、本シリーズのパート 1 で作成した HotStockViewModel の引数のないコンストラクタで初期化するようにしてみましょう。
private final FirebaseQueryLiveData liveData = new FirebaseQueryLiveData(HOT_STOCK_REF);
private final MediatorLiveData<HotStock> hotStockLiveData = new MediatorLiveData<>();

public HotStockViewModel() {
    // Set up the MediatorLiveData to convert DataSnapshot objects into HotStock objects
    hotStockLiveData.addSource(liveData, new Observer<DataSnapshot>() {
        @Override
        public void onChanged(@Nullable final DataSnapshot dataSnapshot) {
            if (dataSnapshot != null) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        hotStockLiveData.postValue(dataSnapshot.getValue(HotStock.class));
                    }
                }).start();
            } else {
                hotStockLiveData.setValue(null);
            }
        }
    });
}

ここでは、ソース LiveData オブジェクトとソースが変更された際に呼び出される Observer を使い、MediatorLiveData インスタンスの addSource() を呼び出しています。onChanged() の内部では、デシリアライズ作業を新しいスレッドにオフロードしています。このスレッド化した作業では、postValue() を使って MediatorLiveData オブジェクトを更新していますが、スレッド化していない作業(dataSnapshot が null の場合)は、setValue() を使っています。この違いは重要です。postValue() による更新はスレッドセーフですが、setValue() はメインスレッド上でのみ呼び出すことができます。

注: 実際のアプリでは、このようにして新しいスレッドを起動することはおすすめしません。これは、動作をスレッド化する「ベスト プラクティス」を示す例ではありません。このようなジョブでは、再利用可能なスレッドのプールとともに Executor を使う方が適しています()。

まだ改善の余地はある


以上で、Activity から Realtime Database オブジェクトを削除することができ、DataSnapshot から HotStock への変換を行う際のパフォーマンスにも対処できました。しかし、パフォーマンスを改善するためにまだできることがあります。Activity に構成変更(端末の回転など)が発生すると、onInactive() が実行されて FirebaseQueryLiveData オブジェクトがデータベース リスナーを削除し、その後 onActive() で再追加されることになります。これはあまり問題にはならないと思うかもしれませんが、/hotstock 以下の全データが(不必要に)往復する点を意識しておくことが重要です。回転が起こったときは、リスナーを追加した状態のままにしておき、ユーザーのデータプランを節約する方が望ましいでしょう。そこで、本シリーズの次のパートでは、これを実現する方法について説明します。

またお会いできることを楽しみにしています。忘れずに Twitter で @Firebase をフォローし、本シリーズの最新情報をチェックしてください!パート 3 は、こちらからご覧いただけます。



Reviewed by Khanh LeViet - Developer Relations Team
Share on Twitter Share on Facebook


次に示す ViewModel 実装は、Realtime Database のロケーション /hotstock をリッスンする FirebaseQueryLiveData を公開しています。
public class HotStockViewModel extends ViewModel {
    private static final DatabaseReference HOT_STOCK_REF =
        FirebaseDatabase.getInstance().getReference("/hotstock");

    private final FirebaseQueryLiveData liveData = new FirebaseQueryLiveData(HOT_STOCK_REF);

    @NonNull
    public LiveData<DataSnapshot> getDataSnapshotLiveData() {
        return liveData;
    }
}

この ViewModel 実装では、LiveData オブジェクトが公開されている点に注目してください。これによって、HotStockViewModel を使う Activity が、基となるデータ(データベースの /hotstock)に対するすべての変更を積極的に監視できるようになります。

Activity で LiveDataViewModel を組み合わせる

これで、LiveDataViewModel の実装が完成したので、Activity からこれらを使うようにします。先ほどの Activity を LiveDataViewModel を使うようにリファクタリングしたものを以下に示します。
public class MainActivity extends AppCompatActivity {
    private TextView tvTicker;
    private TextView tvPrice;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        tvTicker = findViewById(R.id.ticker);
        tvPrice = findViewById(R.id.price);

        // Obtain a new or prior instance of HotStockViewModel from the
        // ViewModelProviders utility class.
        HotStockViewModel viewModel = ViewModelProviders.of(this).get(HotStockViewModel.class);

        LiveData<DataSnapshot> liveData = viewModel.getDataSnapshotLiveData();

        liveData.observe(this, new Observer<DataSnapshot>() {
            @Override
            public void onChanged(@Nullable DataSnapshot dataSnapshot) {
                if (dataSnapshot != null) {
                    // update the UI here with values in the snapshot
                    String ticker = dataSnapshot.child("ticker").getValue(String.class);
                    tvTicker.setText(ticker);
                    Float price = dataSnapshot.child("price").getValue(Float.class);
                    tvPrice.setText(String.format(Locale.getDefault(), "%.2f", price));
                }
            }
        });
    }
}

コードが 20 行ほど短くなり、読みやすく、管理しやすくなりました!

onCreate() の中では、次の短いコードを使って HotStockViewModel インスタンスを取得しています。
HotStockViewModel viewModel = ViewModelProviders.of(this).get(HotStockViewModel.class);

ViewModelProviders は Architecture Components のユーティリティ クラスで、与えられたライフサイクル コンポーネントに基づいて ViewModel インスタンスを管理します。上の行から得られる HotStockViewModel オブジェクトは、次の いずれか となります。Activity として指定されたクラスの ViewModel が存在しない場合、新しく作成されます。 または 構成変更が起こる 前の Activity のインスタンスから取得されます。

HotStockViewModel のインスタンスがあれば、単にオブザーバを追加するだけで LiveData の変更に反応する Activity を作ることができます。そして、データベース内にある基となるデータが変更されるたびに、オブザーバが UI を更新します。

この方式によるメリット

さらに改善するには


新しい Activity の実装を見てみると、Firebase Realtime Database の細かい処理を行う部分は、ほとんどなくなっていることがわかります。そういった部分は、DataSnapshot を扱う部分を除き、FirebaseQueryLiveData に移動しています。理想を言えば、Realtime Database を参照している部分はすべて Activity から削除したいところです。そうすれば、データが実際にどこからやってくるのかを意識する必要はなくなります。Firestore への移行を考える場合は、これが重要になります。まったくではないにしろ、ほとんど Activity を変更しなくてもよくなるからです。

もう 1 点微妙な問題があります。実は、構成変更が起こるたびに、リスナーが削除、再追加されています。リスナーを再追加するということは、実質的にデータを再取得するためにサーバーとの間を一往復しなければならないということです。ユーザーの限られたモバイルデータを消費することがないように、これは避けた方がよいでしょう。ディスク永続性を有効にする方法もありますが、さらによい方法もあります(その秘訣はこのシリーズで紹介するので、お楽しみに!)。

以上の 2 つの問題は、今後の投稿で解決したいと思いますので、ぜひ Firebase ブログに注目してください。また、Twitter で @Firebase をフォローしてください!パート 2 は、こちらからご覧いただけます。



Reviewed by Khanh LeViet - Developer Relations Team
Share on Twitter Share on Facebook




Google では、この新しい体験を Google Play Instant と呼んでいます。試してみるには、Android 端末から Google Play を開き、Instant Gameplay コレクションにアクセスしてください。または、新デザインの Google Play ゲームアプリで「アーケード」にアクセスし、「Instant Gameplay」コレクションからゲームを始めることもできます。Google Play Instant を利用することで、ユーザーは、すぐにソーシャル ネットワークから招待したりマーケティング キャンペーン経由でゲームを共有することが可能になります。

Google Play Instant は現時点ではクローズドベータ版です。ゲーム開発者のニーズをより的確に満たすことができるよう、この機能は Instant Apps フレームワークを拡張しています。たとえば、最大 10MB の APK サイズ、実行可能なコードとゲームアセットのプログレッシブダウンロードのサポート、既存のツールチェーンを使用した NDK やゲームエンジンのサポートなどに対応します。加えて、IDE サポートを追加してより簡単に Instant Apps の開発が行えるよう、Google は Unity や Cocos などのゲーム開発プラットフォームと協力しています。より本格的な展開は、今年の後半以降を予定しています。Google Play Instant の今後の最新情報を入手するには、サインアップしてください。

Jam City, Zynga, King, Hothead Games, Jam City, Playtika, MZ and Manga Mobileといったゲーム開発者のみなさんは、Google Play Instant を使い、新たなユーザーを獲得し、離脱率を下げ、効果的にゲームをクロスプロモーションされました。詳細はこちら

高品質なゲームの開発に向けたGoogle Play Console ツールの提供


素晴らしいゲームを開発できるよう、Google はいくつかの役立つツールも提供します。



これらは 2018 年に予定されている新機能のほんの一部です。ゲームタイトルへの新たなユーザー獲得に貢献する Google Play Instant に関する追加情報は、今後順次ご案内する予定です。


Posted by Ryosuke Matsuuchi - Developer Relations Team
Share on Twitter Share on Facebook


本日、Real-Time Config についての発表がありました。これは、Fast Fetch のスピードとパフォーマンスを活用しつつ、サイトオーナーがサードパーティの技術パートナーを導入できるようにする新たなコンポーネントです。Real-Time Config を使うと、サイトオーナーは収益化戦略で妥協することなく、Fast Fetch のメリットを活用できます。たとえば、AMP ページ上でデータ管理プラットフォームやサーバーサイド デマンド アグリゲーターを利用できるようになります。Prebid Server などがこれに当たります。

新しいツールとパートナーによる AMPHTML 広告の拡大


広告の提供は AMP の収益化に影響する 1 つの要素ですが、もう 1 つの要素となるのが広告クリエイティブ自身です。先日、AMP 広告は「AMPHTML 広告」という新しいブランド名称になりました。知名度の向上を図るとともに、高速で安全な広告をサポートすることが新たな名称の目的です。

AMPHTML 広告は、従来の広告より最大 5 秒早く読み込むことができます。さらに、不正なソフトウェアの拡散を防ぎ、見やすく安全なブランド体験を保証します。また、AMP ページと非 AMP ページの両方で動作するので、クリエイティブの制作者は、広告を 1 回制作するだけでどこにでも提供することができます。

Triplelift、Celtra、DoubleClick など、たくさんの技術パートナーがすでに AMPHTML 広告をサポートしています。本日の AMP Conf では、AdZerkLogicad、Google Web Designer が AMPHTML 広告をサポートすることを発表しました。これによって、ウェブのあらゆる広告体験を高速で安全なものにするという目的に 1 歩近づきます。日本のマーケティング技術プラットフォームである So-net Media Networks(Logicad)は、AMPHTML 広告のサポートを行ったことで、広告の読み込み時間が 33% 短縮され、CTR が 30% 増加しました。

AMPHTML 広告で高速で安全、そして優れたパフォーマンスの広告クリエイティブを提供したいという方は、AMPbyExample に掲載されているいずれかのオープンソース AMPHTML 広告テンプレートを使うか、AMPHTML 広告をサポートしているプラットフォームにご連絡ください。

AMPHTML 広告のデモ gif

AMP Project は、あらゆる人のためにオープンなウェブをさらに高速で優れたものにするという目的のもとで始まりました。パートナーの皆さんが AMP を使って維持可能な形でビジネスを拡大できるように、エコシステム全体と協力しつつ作業を続けてゆきたいと思っています。

1 2018 年 2 月、Google 内部のデータ
2 2018 年 2 月、Internet Live Stats



Reviewed by Yoshifumi Yamaguchi - Developer Relations Team
Share on Twitter Share on Facebook



Reviewed by Thanet Knack Praneenararat - Ads Developer Relations
Share on Twitter Share on Facebook


AMP のエコシステム


AMP の拡大は、ウェブのエコシステム全体からの力強いサポートのおかげでもあります。Baidu、Sogou、VK(ロシア)、360 Search、Twitter など、世界中のプラットフォームやサービスが積極的に AMP ページにリンクしています。特に、Twitter は AMP のサポートによって大きな成果をあげており、AMP で閲覧されないページの読み込みは、非 AMP ページよりも 10% 減少しています。多くのサイトオーナーや企業は、ウェブサイトで CMS プラットフォームを活用しています。Drupal、BigCommerce、Squarespace などのプラットフォームで動作しているサイトは、AMP ページを公開することができます。そして本日、Google は XWP と Automattic と共同で、WordPress AMP プラグインのバージョン 0.7 をリリースしました。これにより、WordPress 全体にわたる AMP サポートが強化されます。ウェブのエコシステムが AMP ページを作成できるようにする取り組みは、今後も続けていく予定です。

新たな場所での AMP の表示


昨年、AMP ができるあらゆることに着目する中で、とても広く使われているある有名な通信チャンネルを AMP を使って最新化できるのではないかという大きな可能性に気づきました。それはメールです。本日、AMP for Email が発表されました。これは、すべてのプラットフォームで、メールに AMP コンポーネントを含める新たな方法になります。多くの人々は、フライト、イベント、ニュース、ショッピングなどの情報をメールで入手しなければなりません。日々送られているメールの数は、2700 億通以上にのぼります。AMP for Email では、メールに動的な最新情報を含めることができ、アクションを行うこともできます。この機能が切り開く可能性を考えると、とても興奮します。デベロッパーや企業は、今まで以上に表現力が高くインタラクティブなメールを送れるようになります。

Pinterest、Booking.com、Doodle などの企業は、すでに AMP for Email を使った新しいエクスペリエンスを構築しています。これから他の企業が何を行うかもとても楽しみです。AMP for Email の仕様は、本日公開されています。Gmail は、今年中にこの仕様に対応する予定です。それまでの間、デベロッパーの皆さんは、こちらから Gmail のデベロッパー プレビュー版にアクセスすることができます。

image1

コミュニティ


AMP のようなオープンソース プロジェクトが成功できるかどうかは、究極的にはウェブからの貢献やサポートを得られるかどうかにかかっています。過去数年にわたっていただいた情報、貢献やサポートに、非常に感謝しています。AMP チーム全体に代わり、お礼を申し上げます。Github の貢献者は 560 名を超えており、その大半(なんと 88%)は Google のコア AMP チーム以外によるものです。そして、いつものように、さらに多くの方々にプロジェクトに関わっていただき、ともに開発を行っていきたいと心から願っています。まずは、毎週の設計レビューから始めることをおすすめします。世界的に参加しやすい時間帯に行われるようになっています。

image4

まだやるべきことは残されていますが、私たちは、ユーザーやサイトが繁栄できるウェブを実現するという情熱を抱いています。ここ、アムステルダムの会場の熱気を皆さんにもお伝えできればと思います。今年の AMP Conf のすべてのセッションは、AMPproject.org/amp-conf からご覧いただけますので、お忘れなく。また、Twitter をフォローして #ampconf ハッシュタグを使ってください。乾杯!


Reviewed by Yoshifumi Yamaguchi - Developer Relations Team
Share on Twitter Share on Facebook

技術的な課題を最小限にして、クリエイターはストーリーを伝えることに集中


モバイルウェブは、コンテンツの配布や共有は得意ですが、そのパフォーマンスを制御するのは難しい場合があります。ユーザーは、ネイティブ アプリで高速かつスムーズな視覚的ストーリーを見ることに慣れていますが、それをウェブで作成するのも難しい場合があります。多くの場合、そういった点にきちんと対処しようとすると、特に小規模なサイトオーナーにとっては、初期費用が莫大なものになります。

AMP Story は、AMP の技術基盤を土台として構築されており、高速で美しいモバイルウェブ エクスペリエンスを提供します。他のウェブページと同じく、サイトオーナーは AMP Story の HTML ページを自分のサイトにホストできます。目に付きやすくするため、サイトのどこからでもリンクすることが可能です。また、検索プラットフォームでは、AMP エコシステムのあらゆるコンテンツと同じように、事前レンダリング可能ページ、動画読み込みの最適化、エンドユーザーへの配信を最適化するキャッシュなどの技術を利用できます。

AMP Story は、技術的な面で、ストーリー制作をできる限り簡素にしています。このフォーマットには、プリセット済みの柔軟なレイアウト テンプレート、標準化された UI コントロール、共有や後続コンテンツの追加に対応したコンポーネントが付属しています。

一方で、デザインの編集にあたっての自由度は非常に高いので、コンテンツのクリエイターはブランドに忠実なストーリーを伝えることができます。AMP Story フォーマットの初期の開発に関わった CNNConde NastHearstMashableMeredithMicVox MediaThe Washington Post といったサイトオーナーは、さまざまなカテゴリのコンテンツで没頭できるストーリーを提供するため、記者、イラストレーター、デザイナー、プロデューサー、動画編集者などを集めてこのフォーマットを独創的な方法で活用し、新たな手法の実験を行いました。

AMP Story のデベロッパー プレビューを開始


本日(*原文公開当時)より、すべての方が自分のウェブサイトで AMP ストーリーを使えるようになっています。AMP Project の一部である AMP Story フォーマットは、誰でも無償で使うことができます。使ってみたい方は、チュートリアルドキュメントをご覧ください。コンテンツのクリエイターや、技術的な貢献者の皆さんからのフィードバックを楽しみにしています。

さらに、本日より、Google 検索で AMP Story を参照できるようになっています。モバイル ブラウザから、g.co/ampstories に掲載されているサイトオーナーの名前(前述の名前など)で検索すると、試してみることができます。今後、Google 全体でさらに多くのサービスやプロダクトに AMP ストーリーが導入される予定です。また、Google 検索での表示方法も拡張される予定です。


Reviewed by Yoshifumi Yamaguchi - Developer Relations Team
Share on Twitter Share on Facebook

最近の AMP By Example の開発スプリントで構築されたハンドスピナーの例

その他の主な新機能



今後のロードマップ



詳しくは、完全なロードマップをご覧ください。

* * *


作業したりフィードバックを寄せてくださっている AMP 開発コミュニティの方々に感謝いたします。いつものように、問題や機能リクエストがありましたら遠慮なく GitHub からお知らせください

Reviewed by Yoshifumi Yamaguchi - Developer Relations Team

Share on Twitter Share on Facebook