UITor2.0.0

Android App Inspector on 💊





Introduction

UITor is a result of my rebranding experiences of one android app what I was working on. Because of the project's complex structure, not using themes, complexity of UI and app itself, it was really hell and time consuming work to finish the app rebranding. Project structure had been done like sub-projects, because of big amount of different assets, logic, etc. I found out also UITor very useful in time of UI refactoring/bugfixing other apps what I didn't know much deeply from UI/structure perspective.

So this is it, combination what I'd met, seen and few my own ideas. You can see a simple (not completely working though) demo here.
Web part is mostly tested with Chrome and Firefox only. Other browsers might have some problems with WebGL or performance. So get Chrome for the best UX…

App is separated into following different screens.

Layout Inspector

Android Studio Layout Inspetor similar screen with a preview, easy to identify and see any of views of current screen. By clicking on particular view, you will get a lot of (public) properties for selected View. Each view behave like a switch between mode detail/focus mode. Click on same view again (in preview/tree) to turn it off again.

3D Inspector

This is presumably the coolest screen in UITor, you can see whole view hierarchy in 3D space. You can though see more easily useless parents, backgrounds or whatever is hidden by z-order. Use mouse + ASD keys for better control over whole 3D app world. Click on any particual view and you will get again view details.

View Hierarchy

Tree graph of the view hierarchy. You can easily see how deep/wide/complex is your view hierarchy. Click on a node shows again details, about particular node (View), Double click collapse/expand tree.

Resources

Simple and effective resources browser running under actual device context. You will see defined drawables, layouts, values for the context of your device (display density, orientation, locale, ...). Specially for drawables and layouts notice Source: for identifying your source if you have some resource qualifier issues.

File Browser

Simple file browser. You can access app folder or SDCard (be sure you have enabled storage permissions). Seeing your shared_prefs.xml file or getting some in-app created files is now super easy… (currently doesn't support Storage Access Framework)

Windows

Simple preview of running activities and all running fragments.

Windows Detailed

This screen shows current running Activities structure including (child) fragments. You can see intents, bundles, some useful values from Activities, Fragments, Dialogs, Navigation etc. Because it's quite complex hierarchy I didn't try to figure out some decent UI for presenting the data so it's just a simple JSON. For better viewing use some nice browser plugin for json beautifing like JSONView or similar tool.

Screenshot

Simple screenshot. As it isn't designed for rooted devices, you won't be able to see Android Notification Bar content at all.

LogCat

Just logcat output showing only the app logs

Groovy

Coding console. Write a script in groovy and let it execute in the app. Supported only for apps having minSdk=26

Save/Load

Snapshot mode. Simply save a current state of the app for later. FileBrowser & Groovy are obviously ignored. Saving resources is configurable via UitorClientConfig.setResourcesInSnapshot(true). Enabled resoruces saving is time consuming and heavily depends on the size of your resources, so be patient, it might take easily upto a minute.

Install UITor

//your app/build.gradle
android {

  //necessary otherwise duplicated files error
  packagingOptions {
        pickFirst 'META-INF/kotlinx-coroutines-core.kotlin_module'
        pickFirst 'META-INF/io.netty.versions.properties'
        exclude 'META-INF/INDEX.LIST'
  }

  //be sure to have Java 1.8 enabled
  //ignoring this configuration might lead into unexpected crashes like
  //No static method metafactory ... appears in /apex/com.android.runtime/javalib/core-oj.jar
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
  // For Kotlin projects
  kotlinOptions {
    jvmTarget = "1.8"
  }

  defaultConfig {           
    //UITor has coroutines & web server as dependency, even small projects will mostlikely
    //hit the 64k methods limit, so be ready for it
    multiDexEnabled true
  }
}

dependecies { 
  implementation 'com.scurab:anuitor:2.0.0'
  if (android.defaultConfig.minSdkVersion >= 26) {
    //groovy support is only for devices with API 26+
    implementation 'com.scurab:anuitor-groovy:2.0.0'
  }

  //be sure you have included Gson or Jackson
  //I do have better experience with Jackson
  //implementation 'com.google.code.gson:gson:2.8.0' 
  implementation 'com.fasterxml.jackson.core:jackson-databind:2.9.2'
}

Start UITor

//get a context reference, app or activity
val context = ...
//start service asyncly
UitorService.startService(context, 8080)

//load your R.class res values 
//mostlikely necessary if you have more than 1 project module, flavors, ...
IdsHelper.loadValues(com.application.R::class.java)

That's it, in a few seconds you should see in Android Notification Bar a notification about running UITor where you can see ip address(es) and port used by the service. Just open it in your browser and you should see exactly same "homepage" like in Demo.

Be sure that your WiFi AP doesn't block communication between you and your device!
Or connect your device via USB and use just `adb forward tcp:8080 tcp:8080`, then you can access it via http://localhost:8080 on your computer.

Custom views

If you want to extract values for your custom view. Just create new implementation of ViewExtractor (or any other subclass) like here.You can found all defined extractors in com.scurab.android.anuitor.extract2 package.

In case your custom view renders outside bounds, you can register a RenderAreaWrapper by DetailExtractor#registerRenderArea . This is only necessary for proper renderin in 3D screen.

Sample

You can easily get a sample application using UITor here or here (API26+ Devices with Groovy support).

Known issues & tips

  • View rendering is done using SW layer. That means that view doesn't have to look exactly same as on device. You're missing shadows for your CardView ? That's exactly it.

  • In right view properties section. Take a look specially Owner, this will tell you what Fragment/Activity is your view located in.

  • If you use MVP or you would like to add some informations from Activity/Fragment etc. Take a look How to add custom extractor for your types

  • Take a look UitorClientConfig You can control few web settings, like type higlighting, add ignoring views for mouse cursor in ScreenPreview.

  • Wondering what classes are supported by UITor ? Take a look this json.

  • 3D preview camera controlling is not the best UX, try to use mouse + ASD keys for rotation/distance/position move.

  • Middle mouse cursor in LayourInspector can disable/enable selectability using a mouse cursor.

Keyboard shortcuts

  • ALT+T - change a light/dark theme
  • ALT+R - delayed reload in 5s (for case you need to put the app into some not simple state)
  • ALT+S - save a snapshot (works only in LayoutInspector, 3D Inspector, Vuew Hierarchy). This might not be working if your browser is using if or some other stuff menu/plugin...
  • Layout Inspector
    • NUM + Scale preview up
    • NUM - Scale preview down
    • NUM * Scale to fit
  • Groovy
    • SHIFT ENTER Execute code

Few words before you start

Small issue here is taking a screenshot. If you have HW acceleration enabled (by default since Honeycomb) there can be a difference between screenshot and real image what you can see on the device. It's because taking a screenshot is hapenning in SW mode (no HW acceleration) as you might know some stuff e.g. Canvas Clipping is not fully implemented with HW acceleration). Unfortunatelly there is no official way how to get the screenshot with HW acceleration, so there is (i guess) no way how to do it.

As the nature of this is inside-app running module, you "can't" start UITor in an app what you don't have source code for, because it needs to get direct references to your view hierarchy children.

License

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.