您的当前位置:首页正文

Intent序列化

2024-11-29 来源:个人技术集锦

在使用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(';');
                }
            }
        }
    }

终于看到全貌了。

转载于:https://my.oschina.net/tingzi/blog/833218

显示全文