Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

View.toString() readout meaning

Tags:

java

android

I'm logging views out to the logcat to distinguish between different views for debug purposes.

What I've noticed is that the output (caused essentially by View.toString) is something like this:

com.example.app.CustomView{7b14550 IFE...C.. ........ 0,0-1440,315}

What does each section between the curly brackets mean?

UPDATE: Just thought the answer may be in the View source code and had a look. For anyone looking to know this there is a toString() method that explains each of the values.

like image 693
Alex Newman Avatar asked Nov 15 '25 09:11

Alex Newman


1 Answers

When you call .toString() to any given class, unless it is overridden, it will call toString() as it's defined in in Object. Every class has Object as a root in some or another way. If you extend one class, that class' superclass is Object. If the class extended extends a different class, that class' superclass is Object. You get the idea here. So from the Object documentation:

/**
 * Returns a string representation of the object. In general, the
 * {@code toString} method returns a string that
 * "textually represents" this object. The result should
 * be a concise but informative representation that is easy for a
 * person to read.
 * It is recommended that all subclasses override this method.
 * <p>
 * The {@code toString} method for class {@code Object}
 * returns a string consisting of the name of the class of which the
 * object is an instance, the at-sign character `{@code @}', and
 * the unsigned hexadecimal representation of the hash code of the
 * object. In other words, this method returns a string equal to the
 * value of:
 * <blockquote>
 * <pre>
 * getClass().getName() + '@' + Integer.toHexString(hashCode())
 * </pre></blockquote>
 *
 * @return  a string representation of the object.
 */
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

Meaning unless you override it, it prints out that. Meaning it prints out the hex string of the class' hash code.

So unless it is overridden to print out something else, it prints out the hex string of the class' hashcode.

But in case of the View class, this is the method it has:

public String toString() {
    StringBuilder out = new StringBuilder(128);
    out.append(getClass().getName());
    out.append('{');
    out.append(Integer.toHexString(System.identityHashCode(this)));
    out.append(' ');
    switch (mViewFlags&VISIBILITY_MASK) {
        case VISIBLE: out.append('V'); break;
        case INVISIBLE: out.append('I'); break;
        case GONE: out.append('G'); break;
        default: out.append('.'); break;
    }
    out.append((mViewFlags&FOCUSABLE_MASK) == FOCUSABLE ? 'F' : '.');
    out.append((mViewFlags&ENABLED_MASK) == ENABLED ? 'E' : '.');
    out.append((mViewFlags&DRAW_MASK) == WILL_NOT_DRAW ? '.' : 'D');
    out.append((mViewFlags&SCROLLBARS_HORIZONTAL) != 0 ? 'H' : '.');
    out.append((mViewFlags&SCROLLBARS_VERTICAL) != 0 ? 'V' : '.');
    out.append((mViewFlags&CLICKABLE) != 0 ? 'C' : '.');
    out.append((mViewFlags&LONG_CLICKABLE) != 0 ? 'L' : '.');
    out.append((mViewFlags&CONTEXT_CLICKABLE) != 0 ? 'X' : '.');
    out.append(' ');
    out.append((mPrivateFlags&PFLAG_IS_ROOT_NAMESPACE) != 0 ? 'R' : '.');
    out.append((mPrivateFlags&PFLAG_FOCUSED) != 0 ? 'F' : '.');
    out.append((mPrivateFlags&PFLAG_SELECTED) != 0 ? 'S' : '.');
    if ((mPrivateFlags&PFLAG_PREPRESSED) != 0) {
        out.append('p');
    } else {
        out.append((mPrivateFlags&PFLAG_PRESSED) != 0 ? 'P' : '.');
    }
    out.append((mPrivateFlags&PFLAG_HOVERED) != 0 ? 'H' : '.');
    out.append((mPrivateFlags&PFLAG_ACTIVATED) != 0 ? 'A' : '.');
    out.append((mPrivateFlags&PFLAG_INVALIDATED) != 0 ? 'I' : '.');
    out.append((mPrivateFlags&PFLAG_DIRTY_MASK) != 0 ? 'D' : '.');
    out.append(' ');
    out.append(mLeft);
    out.append(',');
    out.append(mTop);
    out.append('-');
    out.append(mRight);
    out.append(',');
    out.append(mBottom);
    final int id = getId();
    if (id != NO_ID) {
        out.append(" #");
        out.append(Integer.toHexString(id));
        final Resources r = mResources;
        if (id > 0 && Resources.resourceHasPackage(id) && r != null) {
            try {
                String pkgname;
                switch (id&0xff000000) {
                    case 0x7f000000:
                        pkgname="app";
                        break;
                    case 0x01000000:
                        pkgname="android";
                        break;
                    default:
                        pkgname = r.getResourcePackageName(id);
                        break;
                }
                String typename = r.getResourceTypeName(id);
                String entryname = r.getResourceEntryName(id);
                out.append(" ");
                out.append(pkgname);
                out.append(":");
                out.append(typename);
                out.append("/");
                out.append(entryname);
            } catch (Resources.NotFoundException e) {
            }
        }
    }
    out.append("}");
    return out.toString();
}

And what is printed out means:

7b14550 - hash code identifying the view. Note that this will NOT remain constant, as it after all is a hash.
I - the view is invisible  
F - the view is focusable  
E - the view is enabled  
C - the view is clickable  
0,0-1440,315 - indicates left, top, right and bottom offset.

But as you see from the code above, there are many different keys to be aware of.

And the brackets are there to guide you as to what of the details that are printed out is connected to the View you have called .toString on. As far as I have understood, they have no function outside showing you what of the text printed out belongs to that class.


You can override toString and make it print out whatever data you want: fields, results of methods, or just do nothing


Tips for the future

Next time you wonder what a method does (assuming you use an IDE), CTRL+Left click on the method/field in question. If you use another program, as long as you're running semantic autocomplete backed by a supported LSP, there should still be a way to open the target function. Look up what applies for your editor.

Either way, this opens the target class and shows you the method source and any potential documentation left by the developer(s).

like image 156
Zoe stands with Ukraine Avatar answered Nov 17 '25 08:11

Zoe stands with Ukraine