realmのデータをStethoとstetho-realmでChromeで確認する

Stethoとは

  • Stethoはandroidのデバッグブリッジで、Chrome Developer Toolsを利用して、Chromeからデバッグを行うことができます。Facebookが作っている
  • http://facebook.github.io/stetho/

stetho-realm

  • StethoをRealmに対応したライブラリ

使い方

ライブラリの追加

  • https://github.com/uPhyca/stetho-realm のREADMEに記載されているとおりライブラリを追加すればよさそう。

  • app/build.gradle

repositories {
    maven {
        url 'https://github.com/uPhyca/stetho-realm/raw/master/maven-repo'
    }
}


dependencies {
    implementation 'com.facebook.stetho:stetho:1.5.0'
    implementation 'com.uphyca:stetho_realm:2.1.0'
}

アプリケーションクラスで初期化

  • まず動かしたいので、RealmInspectorModulesProviderの設定はしない
public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        Realm.init(this);

        Stetho.initialize(
                Stetho.newInitializerBuilder(this)
                        .enableDumpapp(Stetho.defaultDumperPluginsProvider(this))
                        .enableWebKitInspector(RealmInspectorModulesProvider.builder(this).build())
                        .build());
    }
}

アプリを起動して、chromeで確認

  • chrome://inspect/#devices
  • inspectをクリックして別ウィンドウが起動すると、アプリがクラッシュする

エラー(クラッシュ)のログ

10-06 19:27:33.084 15134-15257/com.exmple.app E/AndroidRuntime: FATAL EXCEPTION: StethoWorker-main-13
    Process: com.exmple.app, PID: 15134
    java.lang.NoClassDefFoundError: Failed resolution of: Lio/realm/internal/LinkView;
        at java.lang.reflect.Executable.getParameterTypesInternal(Native Method)
        at java.lang.reflect.Method.getParameterTypes(Method.java:179)
        at java.lang.Class.getDeclaredMethods(Class.java:1881)
        at com.facebook.stetho.inspector.MethodDispatcher.buildDispatchTable(MethodDispatcher.java:115)
        at com.facebook.stetho.inspector.MethodDispatcher.findMethodDispatcher(MethodDispatcher.java:53)
        at com.facebook.stetho.inspector.MethodDispatcher.dispatch(MethodDispatcher.java:60)
        at com.facebook.stetho.inspector.ChromeDevtoolsServer.handleRemoteRequest(ChromeDevtoolsServer.java:129)
        at com.facebook.stetho.inspector.ChromeDevtoolsServer.handleRemoteMessage(ChromeDevtoolsServer.java:111)
        at com.facebook.stetho.inspector.ChromeDevtoolsServer.onMessage(ChromeDevtoolsServer.java:87)
        at com.facebook.stetho.websocket.WebSocketSession$1.handleTextFrame(WebSocketSession.java:176)
        at com.facebook.stetho.websocket.WebSocketSession$1.onCompleteFrame(WebSocketSession.java:136)
        at com.facebook.stetho.websocket.ReadHandler.readLoop(ReadHandler.java:44)
        at com.facebook.stetho.websocket.WebSocketSession.handle(WebSocketSession.java:45)
        at com.facebook.stetho.websocket.WebSocketHandler.doUpgrade(WebSocketHandler.java:117)
        at com.facebook.stetho.websocket.WebSocketHandler.handleRequest(WebSocketHandler.java:83)
        at com.facebook.stetho.server.http.LightHttpServer.dispatchToHandler(LightHttpServer.java:84)
        at com.facebook.stetho.server.http.LightHttpServer.serve(LightHttpServer.java:61)
        at com.facebook.stetho.inspector.DevtoolsSocketHandler.onAccepted(DevtoolsSocketHandler.java:52)
        at com.facebook.stetho.server.ProtocolDetectingSocketHandler.onSecured(ProtocolDetectingSocketHandler.java:63)
        at com.facebook.stetho.server.SecureSocketHandler.onAccepted(SecureSocketHandler.java:33)
        at com.facebook.stetho.server.LazySocketHandler.onAccepted(LazySocketHandler.java:36)
        at com.facebook.stetho.server.LocalSocketServer$WorkerThread.run(LocalSocketServer.java:167)
10-06 19:27:33.085 15134-15257/com.exmple.app E/AndroidRuntime: Caused by: java.lang.ClassNotFoundException: Didn't find class "io.realm.internal.LinkView" on path: DexPathList[[zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/base.apk", zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_dependencies_apk.apk", zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_resources_apk.apk", zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_0_apk.apk", zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_1_apk.apk", zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_2_apk.apk", zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_3_apk.apk", zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_4_apk.apk", zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_5_apk.apk", zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_6_apk.apk", zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_7_apk.apk", zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_8_apk.apk", zip file "/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_9_apk.apk"],nativeLibraryDirectories=[/data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/base.apk!/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_dependencies_apk.apk!/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_resources_apk.apk!/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_0_apk.apk!/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_1_apk.apk!/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_2_apk.apk!/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_3_apk.apk!/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_4_apk.apk!/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_5_apk.apk!/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_6_apk.apk!/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_7_apk.apk!/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_8_apk.apk!/lib/x86, /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_slice_9_apk.apk!/lib/x86, /system/lib, /vendor/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:125)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
            ... 22 more
        Suppressed: java.io.IOException: No original dex files found for dex location /data/app/com.exmple.app--lQMycLLlbEZGivbevlyjA==/split_lib_resources_apk.apk
        at dalvik.system.DexFile.openDexFileNative(Native Method)
        at dalvik.system.DexFile.openDexFile(DexFile.java:353)
        at dalvik.system.DexFile.<init>(DexFile.java:100)
        at dalvik.system.DexFile.<init>(DexFile.java:74)
        at dalvik.system.DexPathList.loadDexFile(DexPathList.java:374)
        at dalvik.system.DexPathList.makeDexElements(DexPathList.java:337)
        at dalvik.system.DexPathList.<init>(DexPathList.java:157)
        at dalvik.system.BaseDexClassLoader.<init>(BaseDexClassLoader.java:65)
        at dalvik.system.PathClassLoader.<init>(PathClassLoader.java:64)
        at com.android.internal.os.ClassLoaderFactory.createClassLoader(ClassLoaderFactory.java:73)
        at com.android.internal.os.ClassLoaderFactory.createClassLoader(ClassLoaderFactory.java:88)
        at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:69)
        at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:35)
        at android.app.LoadedApk.createOrUpdateClassLoaderLocked(LoadedApk.java:693)
        at android.app.LoadedApk.getClassLoader(LoadedApk.java:727)
10-06 19:27:33.086 15134-15257/com.exmple.app E/AndroidRuntime:     at android.app.LoadedApk.getResources(LoadedApk.java:954)
        at android.app.ContextImpl.createAppContext(ContextImpl.java:2270)
        at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5639)
        at android.app.ActivityThread.-wrap1(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1656)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

エラー(クラッシュ)の解決方法

  • どうやらstetho-realmはメンテされていないみたいで、Realm3.7.1以上のバージョンはサポートされていないみたい
    • https://stackoverflow.com/questions/51379564/noclassdeffounderror-failed-resolution-of-lio-realm-internal-linkview

コミュニティーがフォークして対応しているもがあるみたい

  • https://github.com/wickedev/stetho-realm
  • リポジトリとバージョンの修正をする

  • app/build.gradle

repositories {
    maven {
        url 'https://github.com/WickeDev/stetho-realm/raw/master/maven-repo'
    }
}

dependencies {
    implementation 'com.facebook.stetho:stetho:1.5.0'
    implementation 'com.uphyca:stetho_realm:2.3.0'
}

もう一つ個人的な問題

  • 他にたくさんライブラリを追加しているので、64K 参照制限にひっかかった。
android {
    defaultConfig {
        ...
        minSdkVersion 21 
        targetSdkVersion 26
        multiDexEnabled true  ★これ追加
    }
    ...
}

  • 最終的には、ProGuard を使用して未使用のコードを削除したい

もう一度アプリを起動して、chromeで確認

  • Resources > Web SQL アプリの.realmデータベースを確認できる