Avoid Internal Getters/Setters

In the source code of Activity.java, I see some methods bellow :

public View findViewById(int id) {
    return getWindow().findViewById(id);
}

and the definition of getWindow method:

public Window getWindow() {
    return mWindow;
}

But as the following rules:

Avoid Internal Getters/Setters

In native languages like C++ it's common practice to use getters (eg i = getCount()) instead of accessing the field directly (i = mCount). This is an excellent habit for C++, because the compiler can usually inline the access, and if you need to restrict or debug field access you can add the code at any time.

On Android, this is a bad idea. Virtual method calls are expensive, much more so than instance field lookups. It's reasonable to follow common object-oriented programming practices and have getters and setters in the public interface, but within a class you should always access fields directly.

Without a JIT, direct field access is about 3x faster than invoking a trivial getter. With the JIT (where direct field access is as cheap as accessing a local), direct field access is about 7x faster than invoking a trivial getter. This is true in Froyo, but will improve in the future when the JIT inlines getter methods.

so I want to know why android developers not access this mWindow object directly? If the JIT of the current android versions cannot inline the access, getWindow().findViewById(id) will costs more time than mWindow.findViewById(id), and findViewById is a rather frequently used method.


You can't access the mWindow property directly - it's private. And I wouldn't care about the speed of findViewById , since you only need to call it once for every view in your layout in your onCreate() method and store the views in members of your activity. You do call findViewById only once per view, don't you? ;-)

However, if you really care about these things, you could call getWindow() for yourself, store it into a local variable and call findViewById on it directly. I wouldn't recommend this because all your performance increasements here are not worth the time and anyway will be obsolete with future versions of the JIT.

If you do this I would be very interested in the amount of microseconds you saved. :-)


First: you can't access it because it's private.

Why is it private?

As you said, accessing members directly is faster. On the other hand, you are invoking a method that isn't very fast as it will lookup for some view in the view hierarchy. So using a method instead of a direct access will incur in a small overhead in terms of percentage of the total time that it would take to perform that task.

Anyway, I believe that the reason for this is encapsulation.

You are invoking something you don't own (that is the Android SDK). So, you shouldn't make any assumptions of whats happening "in the other side". Simply use this method and expect that it will return the view you want (or null if it doesn't exists).

Maybe the next version of android will use a different method to lookup a view, not calling getWindow() . If you use this method, they (Google/Android) can simply mark the method as deprecated and "forward" your invocation to the newest implementation. If you were calling directly getWindow() , maybe you would be looking for something that is no longer placed in there.


We have a reason to smile now...

The android documentation which says to avoid internal getters and setters will change soon, supposedly progruard was added to Gingerbread platform which does a fine job of inlining accessor's, please refer to "Avoid Internal Getters/Setters" is bad advice and these two SO posts.

  • https://stackoverflow.com/a/6716573/892055

  • https://stackoverflow.com/a/4930538/892055

  • 链接地址: http://www.djcxy.com/p/4050.html

    上一篇: Android无法访问本地主机?

    下一篇: 避免内部吸收者/安装者