findView ById()ソースコード解析

2298 ワード

下のコードから言えば、これはActivityで最も多く書かれているコードの一つで、この方法が次にどのように処理されているかを見てみましょう.
textView= (TextView) findViewById(R.id.textView);

Activityでの呼び出しは次のとおりです.
 public View findViewById(int id) {
        return getWindow().findViewById(id);
    }

getWindow()はActivityでは実際にPhoneWindow(com.android.internal.policy.impl.PhoneWindow)オブジェクトであるため、次にPhoneWindowでfindView ById()がどのように実装されているかを見て、PhoneWindow実装はWindowから継承されるので、具体的なコードはWindowクラスでWindowでは以下のように実装される.
public View findViewById(int id) {
        return getDecorView().findViewById(id);
    }

getDecorView()はDecorViewオブジェクトを返します.DecorView(PhoneWindowの内部クラス)オブジェクトを見てみましょう.
 private final class DecorView extends FrameLayout implements RootViewSurfaceTaker

DecorViewにも神秘的な点はなく、FrameLayoutから継承され、findViewByIdメソッドも親によって継承されているので、このfindViewByIdメソッドを一周してよく知られているViewとVie wGroupに迂回したので、ViewとViewGroupの実現を見てもこのメソッドの具体的な実現がわかります.まずViewを見てみましょう.
// , 
 public final View findViewById(int id) {
        if (id < 0) {
            return null;
        }
        return findViewTraversal(id);
    }

 protected View findViewTraversal(int id) {
        if (id == mID) {
            return this;
        }
        return null;
    }


Viewの実装は比較的簡単で、主にfindView byIdを呼び出すときに、このidが自分のidと同じかどうかを見て、同じであれば自分に戻り、異なるであればnullに戻ります.次に、View Groupの実装を見てみましょう.
//ViewGroup  findViewTraversal 
 @Override
    protected View findViewTraversal(int id) {
        if (id == mID) {
            return this;
        }

        final View[] where = mChildren;
        final int len = mChildrenCount;

        for (int i = 0; i < len; i++) {
            View v = where[i];

            if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {
                v = v.findViewById(id);

                if (v != null) {
                    return v;
                }
            }
        }

        return null;
    }

基本的なインプリメンテーションは、自分のサブViewを巡回し、サブViewのfindView ByIdを呼び出し、サブViewで見つかったら戻り、サブViewがView Groupの場合、サブView Groupも自動的にサブを探し、Viewツリー全体の検索を実現します.分割線-----------------まとめるとfindViewById()メソッドで、最終的にはActivity内部というDecorViewのメソッドが呼び出され、それによって下のViewツリーの同じidのViewを巡って返されます.このidがどのように来たのかについては、後で文章を書く時間があります.