AdStir開発チームの吉田と申します。 SDK・JS開発をメインに担当しています。 本日はJavaのリフレクションで、AndroidのChrome Custom Tabsを呼び出してみたいと思います。
リフレクションとは
リフレクションは動的に、クラスやメソッド、フィールドにアクセスできる機能です。
- ライブラリが同梱されている場合のみ実行する
- プライベートなメソッドやフィールドにもアクセスできる
など柔軟な実装ができるようになります。
Chrome Custom Tabs
これまで、アプリからWebページを開く際には、暗黙的Intentを送信してChromeなどのブラウザを起動する方法が一般的でした。 Chrome Custom Tabsを使えば
- ページ表示が高速化される
- ブラウザの見た目をカスタムでき、自分のアプリの一部のような表現ができる
といったメリットを享受することができます。
AdStirでは、Chrome Custom Tabsを導入するかしないかを、パブリッシャー様に選択いただけるようにするため、この機能を使用しています。 Chrome Custom Tabsが導入されていれば使用する、されていなければ通常のブラウザを起動する。と言った具合です。
Chrome Custom Tabsの通常の使い方は以下となります。
1 2 |
CustomTabsIntent tabsIntent = new CustomTabsIntent.Builder().build(); tabsIntent.launchUrl(this, Uri.parse("https://www.google.co.jp")); |
1 2 3 4 |
dependencies { ... compile 'com.android.support:customtabs:25.2.0' } |
とても簡単ですが、customtabsが入っていないとビルドすら通りません。 そこで、このコードをリフレクションを使って書き直してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// パッケージ名を指定して、クラスオブジェクトを取得します。 // インナークラスにアクセスするためには$を使います。 Class clazz = Class.forName("android.support.customtabs.CustomTabsIntent$Builder"); // 引数無しのコンストラクタを取得します。 Constructor constructor = clazz.getConstructor(new Class[]{}); // 引数を指定しないでインスタンスを生成します。 Object o = constructor.newInstance(new Object[]{}); // oオブジェクトからClassクラスを取得して、引数無しのbuildメソッドを取得します。 Method build = o.getClass().getMethod("build"); // メソッドを実行します。oオブジェクトについて実行するためoを第一引数に与えます。 Object tabsIntent = build.invoke(o); // tabsIntentオブジェクトからClassクラスを取得し、 // 第一引数がActivityオブジェクト、第二引数がUriオブジェクトのlaunchUrlメソッドを取得します。 Method launchUrl = tabsIntent.getClass().getMethod("launchUrl", new Class[]{Context.class, Uri.class}); // メソッドを実行します。tabsIntentオブジェクトについて実行するため、tabsIntentを第一引数に与えます。 // 第二引数にlaunchUrlに与える第一引数、第三引数に第二引数を与えます。 launchUrl.invoke(tabsIntent, this, Uri.parse("http://google.co.jp/")); |
以上となります。 本当は例外処理や、CustomTabsIntentクラスが存在するかのチェックなども必要になりますが、概ねこのようにすることで、リフレクションでChrome Custom Tabsを起動することができます。
リフレクションには
- メソッドの呼び出しが遅い
- カプセル化を壊す
- コードが冗長になる
などのデメリットも存在しますが、AdStirでは「モジュールが入っているときだけ利用できる」というリフレクションのメリットに注目し、今回のCustom Tabsや、メディエーション機能などを実現しています。
本日はこれまで。 どうもありがとうございました。