首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >安卓ResolveInfo可打包不是完全不打包的

安卓ResolveInfo可打包不是完全不打包的
EN

Stack Overflow用户
提问于 2017-12-19 23:18:15
回答 1查看 156关注 0票数 0

我遇到了一件我本以为很简单的任务,那就是将一个ResolveInfo对象写到一个包中,然后从这个包中创建一个ResolveInfo。不幸的是,这并不是因为我的代码崩溃并抛出一个java.lang.IllegalStateException。

以下是我的代码

代码语言:javascript
复制
fun failingFunction(resolveInfo:ResolveInfo){
    Log.d(TAG,"original label ${resolveInfo.loadLabel(this.packageManager)}")
    val p = Parcel.obtain()
    resolveInfo.writeToParcel(p, 0)
    val copy = ResolveInfo.CREATOR.createFromParcel(p)
    Log.d(TAG,"copy label ${copy.loadLabel(this.packageManager)}") // throws java.lang.IllegalStateException: Missing ComponentInfo!
}

查看ResolveInfo类的源代码,当ResolveInfo ActivityInfo、ServiceInfo或ProviderInfo属性都不存在时,就会抛出异常。因此,我添加了日志,以检查这些日志是否丢失。

代码语言:javascript
复制
fun failingFunction(resolveInfo:ResolveInfo){
    Log.d(TAG,"original activity info ${resolveInfo.activityInfo}")
    Log.d(TAG,"original service info ${resolveInfo.serviceInfo}")
    Log.d(TAG,"original provider info ${resolveInfo.providerInfo}")
    Log.d(TAG,"original label ${resolveInfo.loadLabel(this.packageManager)}")
    val p = Parcel.obtain()
    resolveInfo.writeToParcel(p, 0)
    val copy = ResolveInfo.CREATOR.createFromParcel(p)
    Log.d(TAG,"copy activity info ${copy.activityInfo}")
    Log.d(TAG,"copy service info ${copy.serviceInfo}")
    Log.d(TAG,"copy provider info ${copy.providerInfo}")
    Log.d(TAG,"copy label ${copy.loadLabel(this.packageManager)}")
}

我的原始ResolveInfo对象有一个ActivityInfo,但我的副本没有。ActivityInfo实现了Parcelable,所以我不太理解为什么它没有写在Parcel中。根据ResolveInfo的来源,它应该写在包裹中,并从其中读取:

代码语言:javascript
复制
public void writeToParcel(Parcel dest, int parcelableFlags) {
    if (activityInfo != null) {
        dest.writeInt(1);
        activityInfo.writeToParcel(dest, parcelableFlags);
    } else if (serviceInfo != null) {
        dest.writeInt(2);
        serviceInfo.writeToParcel(dest, parcelableFlags);
    } else if (providerInfo != null) {
        dest.writeInt(3);
        providerInfo.writeToParcel(dest, parcelableFlags);
    } else {
        dest.writeInt(0);
    }
    if (filter != null) {
        dest.writeInt(1);
        filter.writeToParcel(dest, parcelableFlags);
    } else {
        dest.writeInt(0);
    }
    dest.writeInt(priority);
    dest.writeInt(preferredOrder);
    dest.writeInt(match);
    dest.writeInt(specificIndex);
    dest.writeInt(labelRes);
    TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags);
    dest.writeInt(icon);
    dest.writeString(resolvePackageName);
    dest.writeInt(targetUserId);
    dest.writeInt(system ? 1 : 0);
    dest.writeInt(noResourceId ? 1 : 0);
    dest.writeInt(iconResourceId);
    dest.writeInt(handleAllWebDataURI ? 1 : 0);
    dest.writeInt(isInstantAppAvailable ? 1 : 0);
}

private ResolveInfo(Parcel source) {
    activityInfo = null;
    serviceInfo = null;
    providerInfo = null;
    switch (source.readInt()) {
        case 1:
            activityInfo = ActivityInfo.CREATOR.createFromParcel(source);
            break;
        case 2:
            serviceInfo = ServiceInfo.CREATOR.createFromParcel(source);
            break;
        case 3:
            providerInfo = ProviderInfo.CREATOR.createFromParcel(source);
            break;
        default:
            Slog.w(TAG, "Missing ComponentInfo!");
            break;
    }
    if (source.readInt() != 0) {
        filter = IntentFilter.CREATOR.createFromParcel(source);
    }
    priority = source.readInt();
    preferredOrder = source.readInt();
    match = source.readInt();
    specificIndex = source.readInt();
    labelRes = source.readInt();
    nonLocalizedLabel
            = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
    icon = source.readInt();
    resolvePackageName = source.readString();
    targetUserId = source.readInt();
    system = source.readInt() != 0;
    noResourceId = source.readInt() != 0;
    iconResourceId = source.readInt();
    handleAllWebDataURI = source.readInt() != 0;
    instantAppAvailable = isInstantAppAvailable = source.readInt() != 0;
}

有没有人知道为什么这个嵌套的Parcelable没有正确解包?我是否遗漏了我应该使用的有用标志?

谢谢,

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-20 23:35:39

好了,我已经找到了解决问题的方法,它与Parcelable Creator方法无关,而是与我使用Parcel的方式有关。一旦你完成了在包中的编写,你就必须以0作为参数值来调用setDataPosition。

我的代码现在如下:

代码语言:javascript
复制
fun failingFunction(resolveInfo:ResolveInfo){
    Log.d(TAG,"original label ${resolveInfo.loadLabel(this.packageManager)}")
    val p = Parcel.obtain()
    resolveInfo.writeToParcel(p, 0)
    p.setDataPosition(0)
    val copy = ResolveInfo.CREATOR.createFromParcel(p)
    Log.d(TAG,"copy label ${copy.loadLabel(this.packageManager)}") // no longer throws java.lang.IllegalStateException
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47890020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档