Intent源码详解,直接开始入题:
Intent源码6700多行代码,但真正核心代码 就那么几百行,大部分都用来定义常量字符串了
先来看一下
public class Intent implements Parcelable, Cloneable
没错,它还实现了cloneable接口,但平常我们很少会用到它,其实现方法为:
/** * Copy constructor. */ public Intent(Intent o) { this.mAction = o.mAction; this.mData = o.mData; this.mType = o.mType; this.mPackage = o.mPackage; this.mComponent = o.mComponent; this.mFlags = o.mFlags; if (o.mCategories != null) { this.mCategories = new HashSet<String>(o.mCategories); } if (o.mExtras != null) { this.mExtras = new Bundle(o.mExtras); } if (o.mSourceBounds != null) { this.mSourceBounds = new Rect(o.mSourceBounds); } if (o.mSelector != null) { this.mSelector = new Intent(o.mSelector); } if (o.mClipData != null) { this.mClipData = new ClipData(o.mClipData); } } @Override public Object clone() { return new Intent(this); }
没错,就是复制了一个自己
Intent另一个功能,就是传参,这里只展示public Intent putExtra(String name, String value),其他的都是类似这个写法:
public Intent putExtra(String name, String value) { if (mExtras == null) { mExtras = new Bundle(); } mExtras.putString(name, value); return this; }
其中,mExtras是private Bundle mExtras;
那么,这里还得说一下public Intent putExtras(Bundle extras)方法:
public Intent putExtras(Bundle extras) { if (mExtras == null) { mExtras = new Bundle(); } mExtras.putAll(extras); return this; }
没错,bundle中放入一个bundle。。。
再看一下取出的方法:
public String getStringExtra(String name) { return mExtras == null ? null : mExtras.getString(name); }
小结:如果是基本数据类型(Int,long,double,boolean,string)传参,没必要自己生成一个bundle对象,再传参到Intent中。
接下来,聊聊 parseUri 这个方法,里面传的参数是 uri,但到里面,基本就是按照字符串解析
随便摘取几段
// simple case i = uri.lastIndexOf("#"); if (i == -1) return new Intent(ACTION_VIEW, Uri.parse(uri)); // old format Intent URI if (!uri.startsWith("#Intent;", i)) return getIntentOld(uri);
另一个被忽略的是toString()方法,Intent的重写了该方法,可以通过输出String查看Intnet里具体包含的信息内容
@Override public String toString() { StringBuilder b = new StringBuilder(128); b.append("Intent { "); toShortString(b, true, true, true, false); b.append(" }"); return b.toString(); }
那么toShortString()这个方法,到底输出了哪些内容?
可以通过传参的名字了解一二,
public void toShortString(StringBuilder b, boolean secure, boolean comp, boolean extras, boolean clip) {
secure对应的是 uri的输出,
comp对应的是ComponentName 也就是要启动的类名,
extras对应的就是传参内容。
小结,如果在调试过程的时候,可以试着输出Intent内容,看看是否是传参错误导致的异常