joy keeps flowin'

不要给View加context类型参数

xx

工作的这几年,看见过很多次这种写法,很不爽,想吐槽。

明明View里就有个Context的变量,还要画蛇添足,再加个参数保存Context,这个Context很大概率是Activity。

恐怕是忘了传入View里的这个Context就是Activity本人吧。

来看下Activity设置内容View:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// AppCompatDelegateImpl.java
// Activity解析xml布局文件的代码
@Override
public void setContentView(int resId) {
    ensureSubDecor();
    ViewGroup contentParent = mSubDecor.findViewById(android.R.id.content);
    contentParent.removeAllViews();
    LayoutInflater.from(mContext).inflate(resId, contentParent);
    mAppCompatWindowCallback.bypassOnContentChanged(mWindow.getCallback());
}

// LayoutInflater.java

// getContext
// mContext就是从Activity里传进来的兄弟
public Context getContext() {
    return mContext;
}

// 中调用到的inflate方法
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
    final Resources res = getContext().getResources();
    if (DEBUG) {
        Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" ("
                + Integer.toHexString(resource) + ")");
    }

    View view = tryInflatePrecompiled(resource, res, root, attachToRoot);
    if (view != null) {
        return view;
    }
    XmlResourceParser parser = res.getLayout(resource);
    try {
        return inflate(parser, root, attachToRoot);
    } finally {
        parser.close();
    }
}

// 再往下走
private @Nullable View tryInflatePrecompiled(@LayoutRes int resource, Resources res, @Nullable ViewGroup root,
        boolean attachToRoot) {
    ...

    // Try to inflate using a precompiled layout.
    String pkg = res.getResourcePackageName(resource);
    String layout = res.getResourceEntryName(resource);

    try {
        Class clazz = Class.forName("" + pkg + ".CompiledView", false, mPrecompiledClassLoader);
        Method inflater = clazz.getMethod(layout, Context.class, int.class);
        View view = (View) inflater.invoke(null, mContext, resource);

        if (view != null && root != null) {
            // We were able to use the precompiled inflater, but now we need to do some work to
            // attach the view to the root correctly.
            XmlResourceParser parser = res.getLayout(resource);
            try {
                AttributeSet attrs = Xml.asAttributeSet(parser);
                advanceToRootNode(parser);
                ViewGroup.LayoutParams params = root.generateLayoutParams(attrs);

                if (attachToRoot) {
                    root.addView(view, params);
                } else {
                    view.setLayoutParams(params);
                }
            } finally {
                parser.close();
            }
        }

        return view;
    } catch (Throwable e) {
        if (DEBUG) {
            Log.e(TAG, "Failed to use precompiled view", e);
        }
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_VIEW);
    }
    return null;
}

都写明白了View view = (View) inflater.invoke(null, mContext, resource);传入的还是他。

不明白🏳️。

标签:
Categories: