Intent序列化

在使用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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AIDL 回调函数的序列化可以通过以下步骤实现: 1. 在 AIDL 接口中声明回调函数,并在服务端实现回调函数。 2. 在服务端将回调函数所属的对象实现 Parcelable 接口,以便能够进行序列化。 3. 客户端需要实现 AIDL 接口中的回调函数,并将回调函数所属的对象传递给服务端。 4. 在服务端调用回调函数时,将对象序列化后通过 AIDL 接口传递给客户端。 5. 在客户端接收到回调函数时,通过反序列化将对象还原成原来的对象。 以下是一个示例代码: 服务端: ```aidl // MyService.aidl interface MyService { void registerCallback(in ICallback callback); } // MyService.java public class MyServiceImpl extends MyService.Stub { private ICallback mCallback; @Override public void registerCallback(ICallback callback) { mCallback = callback; } public void notifyCallback() { if (mCallback != null) { try { MyObject obj = new MyObject(); Parcel parcel = Parcel.obtain(); obj.writeToParcel(parcel, 0); parcel.setDataPosition(0); mCallback.onCallback(obj); } catch (RemoteException e) { e.printStackTrace(); } } } } // MyObject.java public class MyObject implements Parcelable { private int mValue; @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mValue); } @Override public int describeContents() { return 0; } public static final Creator<MyObject> CREATOR = new Creator<MyObject>() { @Override public MyObject createFromParcel(Parcel in) { return new MyObject(in); } @Override public MyObject[] newArray(int size) { return new MyObject[size]; } }; private MyObject(Parcel in) { mValue = in.readInt(); } } ``` 客户端: ```aidl // MyCallback.aidl interface ICallback { void onCallback(in MyObject obj); } // MyCallback.java public class MyCallbackImpl extends ICallback.Stub { @Override public void onCallback(MyObject obj) { // deserialize MyObject } } // MainActivity.java public class MainActivity extends AppCompatActivity { private MyService mService; private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { mService = MyService.Stub.asInterface(iBinder); try { mService.registerCallback(new MyCallbackImpl()); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName componentName) { mService = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(this, MyService.class); bindService(intent, mConnection, BIND_AUTO_CREATE); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值