Hyperion-AndroidでAndroidアプリをデバッグしよう


shibuya.apk #24でLTする内容になります。(ネタバレになるので来る方はその時に見てください )

Hyperion-Android

Hyperion-AndroidはStethoやLeakCanary、DebugAlter(宣伝)などと同じデバッグ時のみ有効にさせるライブラリです

  • デバッグメニューをアプリに追加できる
  • 一つ一つのメニューが便利
  • Google AutoServiceにより、dependencyに追加するだけで、コードを編集せずに機能を追加できる

端末を振るか通知をタップするとこんな感じでデバッグメニューが出てきます。

Hyperion-Androidの機能紹介

hyperion-attr

おすすめ度 ★
* ViewのAttributeを見れる
* Enableなどを切り替えたりも出来る

hyperion-measurement

おすすめ度 ★★★★★
ZeplinのようにViewとViewの間や
Viewの大きさをdp単位で見ることが
出来る
これのために入れるといっても
良い機能
一度使うとこれなしで正確なレイアウトを組めなくなります

hyperion-shared-preferences

おすすめ度 ★★★
Preferenceの値を動的に変更できる
機能

hyperion-recorder

おすすめ度 ★
アプリの動きを動画として保存できる
機能

hyperion-disk

おすすめ度 ★
アプリのデータディレクトリに保存
されいているファイルを見られる機能

hyperion-phoenix

おすすめ度 ★
アプリを再起動しながらデータや
キャッシュを削除できる機能

hyperion-crash

おすすめ度 ★★★★
アプリが強制終了した時に、クラッシュ
ログを表示してくれる機能
地味に便利

サードパーティのプラグイン Hyperion-Chuck

おすすめ度 ★★★
jgilfelt/chuckを呼び出せる機能
アプリ内でHttpのログを確認できる

https://github.com/Commit451/Hyperion-Chuck

hyperion-geiger-counter

おすすめ度 ?
まだ未リリースのようなのですが、フレーム落ちを検知できるようです。(サンプルアプリで使って見ましたがフレーム落ちが起きなかったので試せていません。)

ガンガンメニュー追加しちゃいましょう

プラグインのコントリビューター募集しているっぽい雰囲気なので、コントリビュートしてあげるといいかもです。
https://github.com/willowtreeapps/Hyperion-Android/issues

Hyperion-Androidを導入する上でハマった所とその解決策

自分が若干Hyperion-Androidを入れる上で手間取った所を紹介します。

DataBindingのBinding生成のエラーになる

debugImplementation 'com.willowtreeapps.hyperion:hyperion-core:0.9.21'
debugImplementation 'com.willowtreeapps.hyperion:hyperion-attr:0.9.21'
...

READMEに書いてあるとおりにdependencyにHyperion-Androidを入れてビルドしようとすると自分の環境ではDataBindingのBindingが生成されない系のエラーになりました。

Hyperionが最新のSupport Libraryなどを使っているのが原因でした。

+--- com.willowtreeapps.hyperion:hyperion-core:0.9.21
|    +--- com.willowtreeapps.hyperion:hyperion-plugin:0.9.21
|    +--- com.android.support:appcompat-v7:27.1.0 (*)
|    +--- com.android.support:recyclerview-v7:27.1.0 (*)
|    \--- com.google.dagger:dagger:2.15
|         \--- javax.inject:javax.inject:1

以下のように除外して対応できました
(逆にHyperionがうまく動かなくなる部分があるかもしれません。)

  ["hyperion-core", "hyperion-attr", "hyperion-measurement", "hyperion-disk", "hyperion-recorder","hyperion-phoenix","hyperion-crash"].forEach {
    debugImplementation ("com.willowtreeapps.hyperion:$it:0.9.20"){
      exclude group: 'com.android.support'
      exclude group: 'com.google.dagger'
    }
  }

既存のデバッグメニューは
どうするか?

すでにアプリにデバッグメニューが実装されている場合、どのように対応しますか?
* 既存のデバッグメニューは消す?
* 自分でPluginを作る?
* ???

既存のデバッグメニューを開くために自分でPluginを作る


GoogleのAutoServiceをkaptで依存する(Kotlinなどの対応状況による。)

以下をモジュールで作って、そのモジュールをdebugImplementationで参照します。

  implementation 'com.willowtreeapps.hyperion:hyperion-plugin:0.9.21'  
  kapt "com.google.auto.service:auto-service:1.0-rc4"

以下のようにプラグインを作る。
ポイントは以下

  • AutoServiceアノテーションを使う(ライブラリとして使う場合)
  • Pluginクラスを作りそこでPluginModuleを作成
  • PluginModuleクラスでViewを作って返す
  • PluginModuleクラスには
色々便利なメソッドが生えているので利用してみると良さそう
@AutoService(Plugin.class)
class HelloWorldPlugin extends Plugin {
    @Override
    public PluginModule createPluginModule() {
        return new HelloWorldPluginModule();
    }
}

class HelloWorldPluginModule extends PluginModule {
    @Override
    public View createPluginView(@NonNull LayoutInflater layoutInflater, @NonNull ViewGroup parent) {
        final TextView textView = new TextView(parent.getContext());
        textView.setText("Hello Hyperion Plugin");
        textView.setTextSize(50);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("Hyperion", "goto debugmenu");
            }
        });
        return textView;
    }
}

プラグインをHyperionに追加する

アプリのモジュール内で実装する場合、
debug/以下ではダメで、main/以下に置かないと
なぜかGoogleのAutoServiceは拾ってくれないので
メニューに追加されないので、プロダクション環境にコードを追加しないとHyperionに既存のデバッグメニューへの導線を追加できません。
別モジュールにすればいいですが、そうするとアプリ内のコードをそのモジュールから参照できません。

プルリク出してAutoServiceを使わずにアプリ内で自分で追加できるようにしました!
このように自分でプラグインを追加して、メニューを追加することができます。

        PluginSource source = Hyperion.getPluginSource();
        class MyPluginSource implements PluginSource {
            private PluginSource originalPluginSource;

            MyPluginSource(PluginSource originalPluginSource) {
                this.originalPluginSource = originalPluginSource;
            }

            @Override
            public Set<Plugin> getPlugins() {
                final HashSet<Plugin> plugins = new HashSet<>();
                plugins.addAll(originalPluginSource.getPlugins());
                // ここで追加したいプラグインを指定する
                plugins.add(new HelloWorldPlugin()); 
                return plugins;
            }
        }
        Hyperion.setPlugins(new MyPluginSource(source));

プラグイン作るの面倒?

わざわざ自分でプラグインを作らなくても、これを使うと簡単にHyperionにアイテムを追加することができます。(宣伝)
https://github.com/takahirom/Hyperion-Simple-Item

public class DebugApp extends App {
  @Override public void onCreate() {
    super.onCreate();

    final SimpleItem item = new SimpleItem.Builder("all: this is the title")
            .text("this is the text")
            .image(R.drawable.ic_list_black_24dp)
            .clickListener(new View.OnClickListener() {
              @Override public void onClick(View v) {
                Toast.makeText(App.this, "click",Toast.LENGTH_SHORT).show();
              }
            })
            .build();
    SimpleItemHyperionPlugin.addItem(item);

導入Pull Request

DroidKaigi 2018公式アプリでの導入PRです。
https://github.com/DroidKaigi/conference-app-2018/pull/672

まとめ

Hyperion-Android、いい感じなので、入れてみましょう。
DataBindingでエラーが出たら依存関係を疑ってみましょう。
既存のデバッグメニューに飛ばすときはHyperion-Simple-Itemを
入れてみましょう。