AnUitor0.9.11

UI debug tool for Android





Introduction

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

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

App is separated into following different screens.

ScreenPreview

DDMS View hierarchy similar screen with screen 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.

3D

This is presumably the coolest screen in AnUitor, 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 particual view and you will get again view details.

ViewHierarchy

Another view for app. View hierarchy is now presented as a tree structure to see how deep and complex is your view hierarchy structure. Click show 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 used drawables, layouts, values. Specially for drawables and layouts notice Source: for identifying your source if you have some resource qualifier issues.

FileStorage

Simple file browser. You can access app folder or SDCard if you have proper rights. Seeing your shared_prefs.xml file or getting some in-app created files is now super easy…

Windows

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

Screenshot

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

LogCat

Pretty much known logcat output showing only app logs

Groovy

Coding console. Write a script in groovy and let it execute in the app

Install AnUitor

Gradle

android {
  //add following statement if you see 
  //com.android.build.api.transform.TransformException: 
  //  com.android.builder.packaging.DuplicateFileException: 
  //  Duplicate files copied in APK META-INF/LICENSE
  packagingOptions {
    exclude 'META-INF/LICENSE.txt'
  } 
}

dependecies{ 
  compile 'com.scurab:anuitor:0.9.11@aar'

  def supportLib = "25.3.1"
  compile "com.android.support:support-core-ui:${supportLib}"
  compile "com.android.support:support-fragment:${supportLib}"

  compile 'com.google.code.gson:gson:2.8.0'
  compile 'com.google.android.tools:dx:1.7'
  compile 'org.codehaus.groovy:groovy:2.4.8'
}
  • Then optionally update your AndroidManifest.xml
<manifest>
   
   <!-- Optionally allow external storage for file browser -->
   <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

   <application>
   …
   </application>
</manifest>
  • And finally start it somewhere in your code.
Context context = ...;
//start service asyncly
AnUitorService.startService(context);
  • Are you using gradle flavors and your applicationId is different than default one ?
//Load resources manually
try {
   IdsHelper.loadValues(com.application.R.class);
} catch(Exception e) {
   e.printStackTrace();
}

That's it, in a few seconds you should see in Android Notification Bar a notification about running AnUitor 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 (v0.9.1).

Be sure that your WiFi AP doesn't block communication between you and your device!

Custom views

For extracting details about custom views you have two options.

Flag your View subclass by @ExportView annotation and any (even private) field flag by @ExportField annotation with a string as your property name. Then your field values will be used in detail window.

Or write your own code for it, create subclass of ViewExtractor (or any better candidate if your view is not "pure" view). Check classes in com.scurab.android.anuitor.extract.view package. Then register your subclass by DetailExtractor.registerExtractor(Class, Extractor); Translator is just simple helper for translating android magic values as something more human readable, you can just simply pass new Translator().

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

Download

AnUitor is currently published on Maven repository or you can download JAR file directly...

You can easily get a sample application using AnUitor here.

Few words before you start

I mostly did everything with my Nexus 4 (A4.4.3) and worked correctly. As i got 4.4.4 i've noticed sometimes a native crash in some image-processing libraries. The oldest device what i tested AnUitor with was Samsung Galaxy Ace with A2.3.x, it worked slowly and similar crashes with image-processing libraries. It's not perfect but currently i'm not much interested in those bugs as there is not much what i can do with and they were pretty rare.

Another 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 anuitor in app what you don't have source code for, because it needs to get direct references to your view hierarchy children.

If you would like to share ViewHierarchy (of course only really crazy stuff i am interested in :)) of your own app, send me a /viewhierarchy.json (be sure that you don't have any sensitive data there) file and i'll publish it like the ViewHierarchyTree…

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.