在调用findViewById()前,view对象其实已经创建好了,在setContextVIew的时候会创建layout中的控件.
setContentView(R.layout.main);
Activity中
public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
initActionBar();
}
window.class
/**
* Convenience for
* {@link #setContentView(View, android.view.ViewGroup.LayoutParams)}
* to set the screen content from a layout resource. The resource will be
* inflated, adding all top-level views to the screen.
*
* @param layoutResID Resource ID to be inflated.
* @see #setContentView(View, android.view.ViewGroup.LayoutParams)
*/
public abstract void setContentView(int layoutResID);
抽象方法的实现在哪里?
android.view.View.inflate()方法,追后会进入
/**
* Inflate a view from an XML resource. This convenience method wraps the {@link
* LayoutInflater} class, which provides a full range of options for view inflation.
*
* @param context The Context object for your activity or application.
* @param resource The resource ID to inflate
* @param root A view group that will be the parent. Used to properly inflate the
* layout_* parameters.
* @see LayoutInflater
*/
public static View inflate(Context context, int resource, ViewGroup root) {
LayoutInflater factory = LayoutInflater.from(context);
return factory.inflate(resource, root);
}
android.view.LayoutInflater.createView()方法:
/**
* Low-level function for instantiating a view by name. This attempts to
* instantiate a view class of the given <var>name</var> found in this
* LayoutInflater's ClassLoader.
*
* <p>
* There are two things that can happen in an error case: either the
* exception describing the error will be thrown, or a null will be
* returned. You must deal with both possibilities -- the former will happen
* the first time createView() is called for a class of a particular name,
* the latter every time there-after for that class name.
*
* @param name The full name of the class to be instantiated.
* @param attrs The XML attributes supplied for this instance.
*
* @return View The newly instantiated view, or null.
*/
public final View createView(String name, String prefix, AttributeSet attrs)
throws ClassNotFoundException, InflateException {
Constructor<? extends View> constructor = sConstructorMap.get(name);
Class<? extends View> clazz = null;
try {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, name);
if (constructor == null) {
// Class not found in the cache, see if it's real, and try to add it
clazz = mContext.getClassLoader().loadClass(
prefix != null ? (prefix + name) : name).asSubclass(View.class);
if (mFilter != null && clazz != null) {
boolean allowed = mFilter.onLoadClass(clazz);
if (!allowed) {
failNotAllowed(name, prefix, attrs);
}
}
constructor = clazz.getConstructor(mConstructorSignature);
sConstructorMap.put(name, constructor);
} else {
// If we have a filter, apply it to cached constructor
if (mFilter != null) {
// Have we seen this name before?
Boolean allowedState = mFilterMap.get(name);
if (allowedState == null) {
// New class -- remember whether it is allowed
clazz = mContext.getClassLoader().loadClass(
prefix != null ? (prefix + name) : name).asSubclass(View.class);
boolean allowed = clazz != null && mFilter.onLoadClass(clazz);
mFilterMap.put(name, allowed);
if (!allowed) {
failNotAllowed(name, prefix, attrs);
}
} else if (allowedState.equals(Boolean.FALSE)) {
failNotAllowed(name, prefix, attrs);
}
}
}
Object[] args = mConstructorArgs;
args[1] = attrs;
final View view = constructor.newInstance(args);
if (view instanceof ViewStub) {
// always use ourselves when inflating ViewStub later
final ViewStub viewStub = (ViewStub) view;
viewStub.setLayoutInflater(this);
}
return view;
} catch (NoSuchMethodException e) {
InflateException ie = new InflateException(attrs.getPositionDescription()
+ ": Error inflating class "
+ (prefix != null ? (prefix + name) : name));
ie.initCause(e);
throw ie;
} catch (ClassCastException e) {
// If loaded class is not a View subclass
InflateException ie = new InflateException(attrs.getPositionDescription()
+ ": Class is not a View "
+ (prefix != null ? (prefix + name) : name));
ie.initCause(e);
throw ie;
} catch (ClassNotFoundException e) {
// If loadClass fails, we should propagate the exception.
throw e;
} catch (Exception e) {
InflateException ie = new InflateException(attrs.getPositionDescription()
+ ": Error inflating class "
+ (clazz == null ? "<unknown>" : clazz.getName()));
ie.initCause(e);
throw ie;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
Constructor.class
/**
* Returns a new instance of the declaring class, initialized by dynamically
* invoking the constructor represented by this {@code Constructor} object.
* This reproduces the effect of {@code new declaringClass(arg1, arg2, ... ,
* argN)} This method performs the following:
* <ul>
* <li>A new instance of the declaring class is created. If the declaring
* class cannot be instantiated (i.e. abstract class, an interface, an array
* type, or a primitive type) then an InstantiationException is thrown.</li>
* <li>If this Constructor object is enforcing access control (see
* {@link AccessibleObject}) and this constructor is not accessible from the
* current context, an IllegalAccessException is thrown.</li>
* <li>If the number of arguments passed and the number of parameters do not
* match, an IllegalArgumentException is thrown.</li>
* <li>For each argument passed:
* <ul>
* <li>If the corresponding parameter type is a primitive type, the argument
* is unboxed. If the unboxing fails, an IllegalArgumentException is
* thrown.</li>
* <li>If the resulting argument cannot be converted to the parameter type
* via a widening conversion, an IllegalArgumentException is thrown.</li>
* </ul>
* <li>The constructor represented by this {@code Constructor} object is
* then invoked. If an exception is thrown during the invocation, it is
* caught and wrapped in an InvocationTargetException. This exception is
* then thrown. If the invocation completes normally, the newly initialized
* object is returned.
* </ul>
*
* @param args
* the arguments to the constructor
*
* @return the new, initialized, object
*
* @exception InstantiationException
* if the class cannot be instantiated
* @exception IllegalAccessException
* if this constructor is not accessible
* @exception IllegalArgumentException
* if an incorrect number of arguments are passed, or an
* argument could not be converted by a widening conversion
* @exception InvocationTargetException
* if an exception was thrown by the invoked constructor
*
* @see AccessibleObject
*/
public T newInstance(Object... args) throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
return constructNative (args, declaringClass, parameterTypes, slot, flag);
}
private native T constructNative(Object[] args, Class<T> declaringClass,
Class<?>[] parameterTypes, int slot,
boolean noAccessCheck) throws InstantiationException, IllegalAccessException,
InvocationTargetException;
//C++中可调用Java代码