在使用debug看获取到的Intent内容时,显示的是如下内容:
Intent { act=android.intent.action.VIEW dat=#Intent;action=com.ting.testAction;S.package_name=com.ting.testPackage;S.method_name=testMethod;S.params={"intent":" flg=0x10020000 pkg=com.ting.test cmp=com.ting.test/.CodeTestActivity (has extras) } |
注意:红色字体显示的是Intent的data的内容,因为是用的debug,没有显示全。
如此显示,是使用了Intent的toString方法。下面让我们一点一点跟进。
@Override
public String toString() {
StringBuilder b = new StringBuilder(128);
b.append("Intent { ");
toShortString(b, true, true, true, false);
b.append(" }");
return b.toString();
}
Intent的toString方法中使用了toShortString,跟进。
/** @hide */
public void toShortString(StringBuilder b, boolean secure, boolean comp, boolean extras,
boolean clip) {
boolean first = true;
if (mAction != null) {
b.append("act=").append(mAction);
first = false;
}
if (mCategories != null) {
if (!first) {
b.append(' ');
}
first = false;
b.append("cat=[");
for (int i=0; i<mCategories.size(); i++) {
if (i > 0) b.append(',');
b.append(mCategories.valueAt(i));
}
b.append("]");
}
if (mData != null) {
if (!first) {
b.append(' ');
}
first = false;
b.append("dat=");
if (secure) {
b.append(mData.toSafeString());
} else {
b.append(mData);
}
}
if (mType != null) {
if (!first) {
b.append(' ');
}
first = false;
b.append("typ=").append(mType);
}
if (mFlags != 0) {
if (!first) {
b.append(' ');
}
first = false;
b.append("flg=0x").append(Integer.toHexString(mFlags));
}
if (mPackage != null) {
if (!first) {
b.append(' ');
}
first = false;
b.append("pkg=").append(mPackage);
}
if (comp && mComponent != null) {
if (!first) {
b.append(' ');
}
first = false;
b.append("cmp=").append(mComponent.flattenToShortString());
}
if (mSourceBounds != null) {
if (!first) {
b.append(' ');
}
first = false;
b.append("bnds=").append(mSourceBounds.toShortString());
}
if (mClipData != null) {
if (!first) {
b.append(' ');
}
b.append("clip={");
if (clip) {
mClipData.toShortString(b);
} else {
if (mClipData.getDescription() != null) {
first = !mClipData.getDescription().toShortStringTypesOnly(b);
} else {
first = true;
}
mClipData.toShortStringShortItems(b, first);
}
first = false;
b.append('}');
}
if (extras && mExtras != null) {
if (!first) {
b.append(' ');
}
first = false;
b.append("(has extras)");
}
if (mContentUserHint != UserHandle.USER_CURRENT) {
if (!first) {
b.append(' ');
}
first = false;
b.append("u=").append(mContentUserHint);
}
if (mSelector != null) {
b.append(" sel=");
mSelector.toShortString(b, secure, comp, extras, clip);
b.append("}");
}
}
下面我看下红色的dat=内容。
Intent { act=android.intent.action.VIEW dat=#Intent;action=com.ting.testAction;S.package_name=com.ting.testPackage;S.method_name=testMethod;S.params={"intent":" flg=0x10020000 pkg=com.ting.test cmp=com.ting.test/.CodeTestActivity (has extras) } |
它其实是把一个Intent转成Uri,传到data中。下面我们来看一下Intent序列化转成Uri的代码。
public String toUri(int flags) {
......//此处省略
toUriFragment(uri, scheme, Intent.ACTION_VIEW, null, flags);
return uri.toString();
}
Intent的toUri方法中调用到了toUriFragment方法,跟进。
private void toUriFragment(StringBuilder uri, String scheme, String defAction,
String defPackage, int flags) {
StringBuilder frag = new StringBuilder(128);
toUriInner(frag, scheme, defAction, defPackage, flags);
if (mSelector != null) {
frag.append("SEL;");
// Note that for now we are not going to try to handle the
// data part; not clear how to represent this as a URI, and
// not much utility in it.
mSelector.toUriInner(frag, mSelector.mData != null ? mSelector.mData.getScheme() : null,
null, null, flags);
}
if (frag.length() > 0) {
uri.append("#Intent;");
uri.append(frag);
uri.append("end");
}
}
里面用到了toUriInner方法,跟进。
private void toUriInner(StringBuilder uri, String scheme, String defAction,
String defPackage, int flags) {
if (scheme != null) {
uri.append("scheme=").append(scheme).append(';');
}
if (mAction != null && !mAction.equals(defAction)) {
uri.append("action=").append(Uri.encode(mAction)).append(';');
}
if (mCategories != null) {
for (int i=0; i<mCategories.size(); i++) {
uri.append("category=").append(Uri.encode(mCategories.valueAt(i))).append(';');
}
}
if (mType != null) {
uri.append("type=").append(Uri.encode(mType, "/")).append(';');
}
if (mFlags != 0) {
uri.append("launchFlags=0x").append(Integer.toHexString(mFlags)).append(';');
}
if (mPackage != null && !mPackage.equals(defPackage)) {
uri.append("package=").append(Uri.encode(mPackage)).append(';');
}
if (mComponent != null) {
uri.append("component=").append(Uri.encode(
mComponent.flattenToShortString(), "/")).append(';');
}
if (mSourceBounds != null) {
uri.append("sourceBounds=")
.append(Uri.encode(mSourceBounds.flattenToString()))
.append(';');
}
if (mExtras != null) {
for (String key : mExtras.keySet()) {
final Object value = mExtras.get(key);
char entryType =
value instanceof String ? 'S' :
value instanceof Boolean ? 'B' :
value instanceof Byte ? 'b' :
value instanceof Character ? 'c' :
value instanceof Double ? 'd' :
value instanceof Float ? 'f' :
value instanceof Integer ? 'i' :
value instanceof Long ? 'l' :
value instanceof Short ? 's' :
'\0';
if (entryType != '\0') {
uri.append(entryType);
uri.append('.');
uri.append(Uri.encode(key));
uri.append('=');
uri.append(Uri.encode(value.toString()));
uri.append(';');
}
}
}
}
终于看到全貌了。