???????????????????????????????????????????????????????????????????????????任?????????????????????????á?????e?????????????????????????????????????????????????о???????????
?????????????????????Ч????????????в??????????????????????????????????????????Ч??????????????????????£?????????android???????????????????????????????????
????????????android ???????????????????
???????????????LayoutInflater??inflate????????xml?????????view???????????inflate??????
????//??ó?????API?????????xml?????????    
????LayoutInflater layoutInflater = (LayoutInflater)getSystemService();   
????View root = layoutInflater.inflate(R.layout.main?? null??false);
?????????????inflate?????У???????XmlResourceParser??????xml????????????????inflate(parser?? root?? attachToRoot)??
????public View inflate(int resource?? ViewGroup root?? boolean attachToRoot) {
????if (DEBUG) System.out.println("INFLATING from resource: " + resource);
????XmlResourceParser parser = getContext().getResources().getLayout(resource);
????try {
????return inflate(parser?? root?? attachToRoot);
????} finally {
????parser.close();
????}
????}
????????????inflate?????л??????????????????????????????????д???????root???????ж??????????????null??????????????????游????????????????????rInflate???????????????????????
????public View inflate(XmlPullParser parser?? ViewGroup root?? boolean attachToRoot) {
????synchronized (mConstructorArgs) {
????final AttributeSet attrs = Xml.asAttributeSet(parser);
????Context lastContext = (Context)mConstructorArgs[0];
????mConstructorArgs[0] = mContext; //??mConstructorArgs??????????????????View???????
????View result = root;
????try {
????// Look for the root node.
????int type;
????while ((type = parser.next()) != XmlPullParser.START_TAG &&
????type != XmlPullParser.END_DOCUMENT) {
????// Empty
????}
????if (type != XmlPullParser.START_TAG) {
????throw new InflateException(parser.getPositionDescription()
????+ ": No start tag found!");
????}
????final String name = parser.getName(); //?????????API?е????????????View?????????
????if (TAG_MERGE.equals(name)) {
????if (root == null || !attachToRoot) {
????throw new InflateException("<merge /> can be used only with a valid "
????+ "ViewGroup root and attachToRoot=true");
????}
????rInflate(parser?? root?? attrs?? false);
????} else {
????// Temp is the root view that was found in the xml
????View temp;
????if (TAG_1995.equals(name)) {
????temp = new BlinkLayout(mContext?? attrs);
????} else {
????temp = createViewFromTag(root?? name?? attrs);
????}
????ViewGroup.LayoutParams params = null;
????if (root != null) {
????// Create layout params that match root?? if supplied
????params = root.generateLayoutParams(attrs);
????if (!attachToRoot) {
????// Set the layout params for temp if we are not
????// attaching. (If we are?? we use addView?? below)
????temp.setLayoutParams(params);
????}
????}
????// Inflate all children under temp
????rInflate(parser?? temp?? attrs?? true);
????// We are supposed to attach all the views we found (int temp)
????// to root. Do that now.
????if (root != null && attachToRoot) {
????root.addView(temp?? params);
????}
????// Decide whether to return the root that was passed in or the
????// top view found in xml.
????if (root == null || !attachToRoot) {
????result = temp;
????}
????}
????} catch (XmlPullParserException e) {
????//...
????} finally {
????// Don't retain static reference on context.
????mConstructorArgs[0] = lastContext;
????mConstructorArgs[1] = null;
????}
????return result;
????}
????}
???????????rInflate?????????????????ò????????????????????????????view????parentView??
????/**
????* Recursive method used to descend down the xml hierarchy and instantiate
????* views?? instantiate their children?? and then call onFinishInflate().
????*/
????void rInflate(XmlPullParser parser?? View parent?? final AttributeSet attrs??
????boolean finishInflate) throws XmlPullParserException?? IOException {
????final int depth = parser.getDepth();
????int type;
????while (((type = parser.next()) != XmlPullParser.END_TAG ||
????parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
????if (type != XmlPullParser.START_TAG) {
????continue;
????}
????final String name = parser.getName();
????if (TAG_REQUEST_FOCUS.equals(name)) {  //????<requestFocus />???
????parseRequestFocus(parser?? parent);
????} else if (TAG_INCLUDE.equals(name)) {  //????<include />???
????if (parser.getDepth() == 0) {
????throw new InflateException("<include /> cannot be the root element");
????}
????parseInclude(parser?? parent?? attrs); //????<include />???
????} else if (TAG_MERGE.equals(name)) { //????<merge />??? 
????throw new InflateException("<merge /> must be the root element");
????} else if (TAG_1995.equals(name)) {  //????<blink />???
????final View view = new BlinkLayout(mContext?? attrs);
????final ViewGroup viewGroup = (ViewGroup) parent;
????final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
????rInflate(parser?? view?? attrs?? true);
????viewGroup.addView(view?? params);               
????} else {
????//???????????????View???????
????final View view = createViewFromTag(parent?? name?? attrs);
????final ViewGroup viewGroup = (ViewGroup) parent;
????//????generateLayoutParams()???????????LayoutParams???????
????final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
????rInflate(parser?? view?? attrs?? true); //??????????
????viewGroup.addView(view?? params); //OK??????View?????LayoutParams????????View
????}
????}
????if (finishInflate) parent.onFinishInflate();  //?????????????..
????}
??????rInflate??????37?д????У?final View view = createViewFromTag(parent?? name?? attrs)??????????????????????view?????????????????????????????????????????????????μ?Android???
????/**
????* default visibility so the BridgeInflater can override it.
????*/
????View createViewFromTag(View parent?? String name?? AttributeSet attrs) {
????//...
????try {
????//...
????if (view == null) {
????if (-1 == name.indexOf('.')) {
????view = onCreateView(parent?? name?? attrs);
????} else {
????view = createView(name?? null?? attrs);
????}
????}
????return view;
????} catch (InflateException e) {
????//...
????}
????}
???????????onCreateView?????и????????????????????????????createView();???????????CreateView????
????protected View onCreateView(String name?? AttributeSet attrs)
????throws ClassNotFoundException {
????return createView(name?? "android.view."?? attrs);
????}
??????createView(name?? “android.view.”?? attrs)?У????÷?????????android.view.XXX??????TextView??????????????????
?????????LayoutInflater.inflate???????????????
??????????????????????????????????????????????????·????????????????