try { // parser同时也继承了xmlPullParser,所以可以用pull解析来获取此view的根节点 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();
//如果它的根节点是一个merge对象,则必须手动设置此view的父节点,否则抛出异常 //因为由merge创建的xml文件,常常被其他layout所包含 if (TAG_MERGE.equals(name)) { if (root == null || !attachToRoot) { throw new InflateException(" can be used only with a valid " + "ViewGroup root and attachToRoot=true"); }
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); } }
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)) { parseRequestFocus(parser, parent); } else if (TAG_INCLUDE.equals(name)) { if (parser.getDepth() == 0) { throw new InflateException(" cannot be the root element"); } parseInclude(parser, parent, attrs); } else if (TAG_MERGE.equals(name)) { throw new InflateException(" must be the root element"); } else { //看这里,创建view的方法。而且这里已经重新获得了它的 final View view = createViewFromTag(name, attrs); final ViewGroup viewGroup = (ViewGroup) parent; final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs); rInflate(parser, view, attrs); viewGroup.addView(view, params); } }
parent.onFinishInflate(); }
View createViewFromTag(String name, AttributeSet attrs) { if (name.equals("view")) { name = attrs.getAttributeValue(null, "class"); }
if (DEBUG) System.out.println("******** Creating view: " + name);
if (mFilter != null && clazz != null) { boolean allowed = mFilter.onLoadClass(clazz); if (!allowed) { failNotAllowed(name, prefix, attrs); } } //通过参数类型获得一个构造器,参数列表为context,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);
/*package*/ XmlResourceParser loadXmlResourceParser(int id, String type) throws NotFoundException { synchronized (mTmpValue) { /*TypedValue对象保存了一些有关resource 的数据值,比如说,对于一个view来说,在xml 文件中可以定义许多属性,TypedValue保存了其中一个属性的相关信息,包括此属性的值的类型 type,是boolean还是color还是reference还是String,这些在attr.xml文件下都有定义。 它的值的字符串名称;一个属性有多个值时,它从xml文件中获取的值它的顺序data;如果此属性的值 的类型是一个reference则保存它的resource id的等等。 */ TypedValue value = mTmpValue; getValue(id, value, true); if (value.type == TypedValue.TYPE_STRING) { return loadXmlResourceParser(value.string.toString(), id, value.assetCookie, type); } throw new NotFoundException( "Resource ID #0x" + Integer.toHexString(id) + " type #0x" + Integer.toHexString(value.type) + " is not valid"); } }
/** * getValue方法,id表示要查找的控件的 id,outValue是一个对象,用于保存一些属性相关信息 * resolveRefs为true表明,当通过属性id找到xml文件中的标签时,比如是一个 * 它的值是一个引用reference,则继续解析获得这个id的值。这里看AssetManager类的实现*/ public void getValue(int id, TypedValue outValue, boolean resolveRefs) throws NotFoundException { boolean found = mAssets.getResourceValue(id, outValue, resolveRefs); if (found) { return; } throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)); }
/*package*/ XmlResourceParser loadXmlResourceParser(String file, int id, int assetCookie, String type) throws NotFoundException { if (id != 0) { try { //取缓存 synchronized (mCachedXmlBlockIds) { // First see if this block is in our cache. final int num = mCachedXmlBlockIds.length; for (int i=0; i if (mCachedXmlBlockIds[i] == id) { //System.out.println("**** REUSING XML BLOCK! id=" // + id + ", index=" + i); return mCachedXmlBlocks[i].newParser(); } }
//window是由sPolicy对象创建的 public static Window makeNewWindow(Context context) { return sPolicy.makeNewWindow(context); }
//sPolicy对象是通过反射,获取的一个实例 //此类的实现在com.android.internal.policy.impl.Policy中 private static final String POLICY_IMPL_CLASS_NAME = "com.android.internal.policy.impl.Policy";
private static final IPolicy sPolicy;
static { // Pull in the actual implementation of the policy at run-time try { Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME); sPolicy = (IPolicy)policyClass.newInstance(); } catch (ClassNotFoundException ex) { throw new RuntimeException( POLICY_IMPL_CLASS_NAME + " could not be loaded", ex); } catch (InstantiationException ex) { throw new RuntimeException( POLICY_IMPL_CLASS_NAME + " could not be instantiated", ex); } catch (IllegalAccessException ex) { throw new RuntimeException( POLICY_IMPL_CLASS_NAME + " could not be instantiated", ex); } }
找到com.android.internal.policy.impl.Policy类
public PhoneWindow makeNewWindow(Context context) { return new PhoneWindow(context); }
Android中的Toast是一种简易的消息提示框,toast提示框不能被用户点击,toast会根据用户设置的显示时间后自动消失。
创建Toast
两个方法创建Toast
makeText(Context context, int resId, int duration)
参数:context是toast显示在
angular.identiy 描述: 返回它第一参数的函数. 此函数多用于函数是编程. 使用方法: angular.identity(value); 参数详解: Param Type Details value
*
to be returned. 返回值: 传入的value 实例代码:
<!DOCTYPE HTML>
Hierarchical Queries
If a table contains hierarchical data, then you can select rows in a hierarchical order using the hierarchical query clause:
hierarchical_query_clause::=
start with condi
初次接触到socket网络编程,也参考了网络上众前辈的文章。尝试自己也写了一下,记录下过程吧:
服务端:(接收客户端消息并把它们打印出来)
public class SocketServer {
private List<Socket> socketList = new ArrayList<Socket>();
public s