Андроид: LayoutInflater — зачем он нужен?
Класс LayoutInflater содержит метод: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();
        }
    }
Соответственно парсер парсит xml и преобразует в объект класса View;
Когда вы в Activity указываете setContentView(int id);
Вы передаете ссылку на xml. Внутри Activity находится экземпляр класса Window, он парсит ваш xml и получает объект класса View. Дальше при вызове в Activity - findViewById(int id), вы обращаетесь к экземпляру класса Window, в свою очередь он делегирует (передает вызов) экземпляру класса View. 
А класс View содержит метод findViewById(int id), и уже он возвращает искомый объект, соответственно в обоих случаях механизм один и тот же, только LayoutInflater обычно используется для парсинга xml не являющихся layout Activity. Например при отрисовке Fragments и CustomView или при компоновке Activity из Java.
Посмотрите исходники SDK, там очень подробно все описано.
findViewById не работает с xml. Он работает с деревом Viewшек. А вот чтобы это дерево сделать из xml как раз нужен LayoutInflater.